chore: apply Rails/SaveBang cop (#15)
* chore: apply Rails/SaveBang cop * fix: correct locale validation in category model spec * fix: update save methods to avoid Rails/SaveBang cop violations
This commit is contained in:
parent
e0708ca6f8
commit
659c3e7c2f
@ -170,3 +170,10 @@ AllCops:
|
||||
|
||||
Layout/LeadingCommentSpace:
|
||||
Enabled: false
|
||||
|
||||
Rails/SaveBang:
|
||||
Enabled: true
|
||||
AllowedReceivers:
|
||||
- Stripe::Subscription
|
||||
- Stripe::Customer
|
||||
- FactoryBot
|
||||
|
||||
@ -77,7 +77,7 @@ class Messages::Messenger::MessageBuilder
|
||||
rescue Koala::Facebook::ClientError => e
|
||||
# The exception occurs when we are trying fetch the deleted story or blocked story.
|
||||
@message.attachments.destroy_all
|
||||
@message.update(content: I18n.t('conversations.messages.instagram_deleted_story_content'))
|
||||
@message.update!(content: I18n.t('conversations.messages.instagram_deleted_story_content'))
|
||||
Rails.logger.error e
|
||||
{}
|
||||
rescue StandardError => e
|
||||
|
||||
@ -39,7 +39,7 @@ class Api::V1::Accounts::CallbacksController < Api::V1::Accounts::BaseController
|
||||
return if response['instagram_business_account'].blank?
|
||||
|
||||
instagram_id = response['instagram_business_account']['id']
|
||||
facebook_channel.update(instagram_id: instagram_id)
|
||||
facebook_channel.update!(instagram_id: instagram_id)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "Error in set_instagram_id: #{e.message}"
|
||||
end
|
||||
|
||||
@ -16,7 +16,7 @@ class Api::V1::Accounts::Integrations::SlackController < Api::V1::Accounts::Base
|
||||
end
|
||||
|
||||
def update
|
||||
@hook = channel_builder.update(permitted_params[:reference_id])
|
||||
@hook = channel_builder.update_reference_id(permitted_params[:reference_id])
|
||||
render json: { error: I18n.t('errors.slack.invalid_channel_id') }, status: :unprocessable_entity if @hook.blank?
|
||||
end
|
||||
|
||||
|
||||
@ -25,17 +25,17 @@ class Api::V1::Accounts::NotificationsController < Api::V1::Accounts::BaseContro
|
||||
end
|
||||
|
||||
def update
|
||||
@notification.update(read_at: DateTime.now.utc)
|
||||
@notification.update!(read_at: DateTime.now.utc)
|
||||
render json: @notification
|
||||
end
|
||||
|
||||
def unread
|
||||
@notification.update(read_at: nil)
|
||||
@notification.update!(read_at: nil)
|
||||
render json: @notification
|
||||
end
|
||||
|
||||
def destroy
|
||||
@notification.destroy
|
||||
@notification.destroy!
|
||||
head :ok
|
||||
end
|
||||
|
||||
@ -55,7 +55,7 @@ class Api::V1::Accounts::NotificationsController < Api::V1::Accounts::BaseContro
|
||||
|
||||
def snooze
|
||||
updated_meta = (@notification.meta || {}).merge('last_snoozed_at' => nil)
|
||||
@notification.update(snoozed_until: parse_date_time(params[:snoozed_until].to_s), meta: updated_meta) if params[:snoozed_until]
|
||||
@notification.update!(snoozed_until: parse_date_time(params[:snoozed_until].to_s), meta: updated_meta) if params[:snoozed_until]
|
||||
render json: @notification
|
||||
end
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController
|
||||
end
|
||||
|
||||
def archive
|
||||
@portal.update(archive: true)
|
||||
@portal.update!(archive: true)
|
||||
head :ok
|
||||
end
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ class Api::V1::ProfilesController < Api::BaseController
|
||||
end
|
||||
|
||||
def set_active_account
|
||||
@user.account_users.find_by(account_id: profile_params[:account_id]).update(active_at: Time.now.utc)
|
||||
@user.account_users.find_by(account_id: profile_params[:account_id]).update!(active_at: Time.now.utc)
|
||||
head :ok
|
||||
end
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ class Api::V1::Widget::ContactsController < Api::V1::Widget::BaseController
|
||||
contact = @contact
|
||||
end
|
||||
|
||||
@contact_inbox.update(hmac_verified: true) if should_verify_hmac? && valid_hmac?
|
||||
@contact_inbox.update!(hmac_verified: true) if should_verify_hmac? && valid_hmac?
|
||||
|
||||
identify_contact(contact)
|
||||
end
|
||||
|
||||
@ -5,7 +5,7 @@ class Platform::Api::V1::AccountsController < PlatformController
|
||||
@resource = Account.create!(account_params)
|
||||
update_resource_features
|
||||
@resource.save!
|
||||
@platform_app.platform_app_permissibles.find_or_create_by(permissible: @resource)
|
||||
@platform_app.platform_app_permissibles.find_or_create_by!(permissible: @resource)
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
@ -12,7 +12,7 @@ class Platform::Api::V1::AgentBotsController < PlatformController
|
||||
@resource = AgentBot.new(agent_bot_params.except(:avatar_url))
|
||||
@resource.save!
|
||||
process_avatar_from_url
|
||||
@platform_app.platform_app_permissibles.find_or_create_by(permissible: @resource)
|
||||
@platform_app.platform_app_permissibles.find_or_create_by!(permissible: @resource)
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
@ -31,7 +31,7 @@ class Public::Api::V1::Inboxes::ContactsController < Public::Api::V1::InboxesCon
|
||||
return if params[:identifier_hash].blank? && !@inbox_channel.hmac_mandatory
|
||||
raise StandardError, 'HMAC failed: Invalid Identifier Hash Provided' unless valid_hmac?
|
||||
|
||||
@contact_inbox.update(hmac_verified: true) if @contact_inbox.present?
|
||||
@contact_inbox.update!(hmac_verified: true) if @contact_inbox.present?
|
||||
end
|
||||
|
||||
def valid_hmac?
|
||||
|
||||
@ -18,7 +18,7 @@ class SuperAdmin::AppConfigsController < SuperAdmin::ApplicationController
|
||||
params['app_config'].each do |key, value|
|
||||
next unless @allowed_configs.include?(key)
|
||||
|
||||
i = InstallationConfig.where(name: key).first_or_create(value: value, locked: false)
|
||||
i = InstallationConfig.where(name: key).first_or_create!(value: value, locked: false)
|
||||
i.value = value
|
||||
i.save!
|
||||
end
|
||||
|
||||
@ -26,7 +26,7 @@ class BulkActionsJob < ApplicationJob
|
||||
records.each do |conversation|
|
||||
bulk_add_labels(conversation)
|
||||
bulk_snoozed_until(conversation)
|
||||
conversation.update(params) if params
|
||||
conversation.update!(params) if params
|
||||
end
|
||||
end
|
||||
|
||||
@ -54,7 +54,7 @@ class BulkActionsJob < ApplicationJob
|
||||
return unless @params[:labels] && @params[:labels][:remove]
|
||||
|
||||
labels = conversation.label_list - @params[:labels][:remove]
|
||||
conversation.update(label_list: labels)
|
||||
conversation.update!(label_list: labels)
|
||||
end
|
||||
|
||||
def records_to_updated(ids)
|
||||
|
||||
@ -17,7 +17,7 @@ class Conversations::UserMentionJob < ApplicationJob
|
||||
account_id: account_id
|
||||
)
|
||||
else
|
||||
mention.update(mentioned_at: Time.zone.now)
|
||||
mention.update!(mentioned_at: Time.zone.now)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -35,7 +35,7 @@ class ConversationReplyMailer < ApplicationMailer
|
||||
init_conversation_attributes(message.conversation)
|
||||
@message = message
|
||||
reply_mail_object = prepare_mail(true)
|
||||
message.update(source_id: reply_mail_object.message_id)
|
||||
message.update!(source_id: reply_mail_object.message_id)
|
||||
end
|
||||
|
||||
def conversation_transcript(conversation, to_email)
|
||||
|
||||
@ -107,7 +107,7 @@ class Article < ApplicationRecord
|
||||
|
||||
root_article_id = self.class.find_root_article_id(article)
|
||||
|
||||
update(associated_article_id: root_article_id) if root_article_id.present?
|
||||
update!(associated_article_id: root_article_id) if root_article_id.present?
|
||||
end
|
||||
|
||||
# Make sure we always associate the parent's associated id to avoid the deeper associations od articles.
|
||||
|
||||
@ -49,7 +49,7 @@ class Channel::TwilioSms < ApplicationRecord
|
||||
params = send_message_from.merge(to: to, body: body)
|
||||
params[:media_url] = media_url if media_url.present?
|
||||
params[:status_callback] = twilio_delivery_status_index_url
|
||||
client.messages.create(**params)
|
||||
client.messages.create!(**params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -3,12 +3,12 @@ module ConversationMuteHelpers
|
||||
|
||||
def mute!
|
||||
resolved!
|
||||
contact.update(blocked: true)
|
||||
contact.update!(blocked: true)
|
||||
create_muted_message
|
||||
end
|
||||
|
||||
def unmute!
|
||||
contact.update(blocked: false)
|
||||
contact.update!(blocked: false)
|
||||
create_unmuted_message
|
||||
end
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ module Featurable
|
||||
|
||||
def enable_features!(*)
|
||||
enable_features(*)
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def disable_features(*names)
|
||||
@ -38,7 +38,7 @@ module Featurable
|
||||
|
||||
def disable_features!(*)
|
||||
disable_features(*)
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def feature_enabled?(name)
|
||||
|
||||
@ -159,12 +159,12 @@ class Conversation < ApplicationRecord
|
||||
# FIXME: implement state machine with aasm
|
||||
self.status = open? ? :resolved : :open
|
||||
self.status = :open if pending? || snoozed?
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def toggle_priority(priority = nil)
|
||||
self.priority = priority.presence
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def bot_handoff!
|
||||
|
||||
@ -268,7 +268,7 @@ class Message < ApplicationRecord
|
||||
end
|
||||
|
||||
def update_contact_activity
|
||||
sender.update(last_activity_at: DateTime.now) if sender.is_a?(Contact)
|
||||
sender.update!(last_activity_at: DateTime.now) if sender.is_a?(Contact)
|
||||
end
|
||||
|
||||
def update_waiting_since
|
||||
@ -276,9 +276,9 @@ class Message < ApplicationRecord
|
||||
Rails.configuration.dispatcher.dispatch(
|
||||
REPLY_CREATED, Time.zone.now, waiting_since: conversation.waiting_since, message: self
|
||||
)
|
||||
conversation.update(waiting_since: nil)
|
||||
conversation.update!(waiting_since: nil)
|
||||
end
|
||||
conversation.update(waiting_since: created_at) if incoming? && conversation.waiting_since.blank?
|
||||
conversation.update!(waiting_since: created_at) if incoming? && conversation.waiting_since.blank?
|
||||
end
|
||||
|
||||
def human_response?
|
||||
@ -296,7 +296,7 @@ class Message < ApplicationRecord
|
||||
|
||||
if valid_first_reply?
|
||||
Rails.configuration.dispatcher.dispatch(FIRST_REPLY_CREATED, Time.zone.now, message: self, performed_by: Current.executed_by)
|
||||
conversation.update(first_reply_created_at: created_at, waiting_since: nil)
|
||||
conversation.update!(first_reply_created_at: created_at, waiting_since: nil)
|
||||
else
|
||||
update_waiting_since
|
||||
end
|
||||
|
||||
@ -66,6 +66,6 @@ class Portal < ApplicationRecord
|
||||
def config_json_format
|
||||
config['default_locale'] = default_locale
|
||||
denied_keys = config.keys - CONFIG_JSON_KEYS
|
||||
errors.add(:cofig, "in portal on #{denied_keys.join(',')} is not supported.") if denied_keys.any?
|
||||
errors.add(:config, "in portal on #{denied_keys.join(',')} is not supported.") if denied_keys.any?
|
||||
end
|
||||
end
|
||||
|
||||
@ -36,7 +36,7 @@ class Team < ApplicationRecord
|
||||
# @return [Array<User>] Array of newly added members
|
||||
def add_members(user_ids)
|
||||
team_members_to_create = user_ids.map { |user_id| { user_id: user_id } }
|
||||
created_members = team_members.create(team_members_to_create)
|
||||
created_members = team_members.create!(team_members_to_create)
|
||||
added_users = created_members.filter_map(&:user)
|
||||
|
||||
update_account_cache
|
||||
|
||||
@ -46,7 +46,7 @@ class ActionService
|
||||
return if labels.empty?
|
||||
|
||||
labels = @conversation.label_list - labels
|
||||
@conversation.update(label_list: labels)
|
||||
@conversation.update!(label_list: labels)
|
||||
end
|
||||
|
||||
def assign_team(team_ids = [])
|
||||
|
||||
@ -10,7 +10,7 @@ class AutoAssignment::AgentAssignmentService
|
||||
|
||||
def perform
|
||||
new_assignee = find_assignee
|
||||
conversation.update(assignee: new_assignee) if new_assignee
|
||||
conversation.update!(assignee: new_assignee) if new_assignee
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -53,7 +53,7 @@ class DataImport::ContactManager
|
||||
contact.email = params[:email] if params[:email].present?
|
||||
contact.phone_number = format_phone_number(params[:phone_number]) if params[:phone_number].present?
|
||||
update_contact_attributes(params, contact)
|
||||
contact.save
|
||||
contact.save # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -27,6 +27,6 @@ class Instagram::WebhooksBaseService
|
||||
# TODO: Remove this once we show the social_instagram_user_name in the UI instead of the username
|
||||
@contact.additional_attributes = @contact.additional_attributes.merge({ 'social_profiles': { 'instagram': user['username'] } })
|
||||
@contact.additional_attributes = @contact.additional_attributes.merge({ 'social_instagram_user_name': user['username'] })
|
||||
@contact.save
|
||||
@contact.save!
|
||||
end
|
||||
end
|
||||
|
||||
@ -29,7 +29,7 @@ class Twilio::WebhookSetupService
|
||||
else
|
||||
twilio_client
|
||||
.incoming_phone_numbers(phonenumber_sid)
|
||||
.update(sms_method: 'POST', sms_url: twilio_callback_index_url)
|
||||
.update(sms_method: 'POST', sms_url: twilio_callback_index_url) # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ class Whatsapp::Providers::Whatsapp360DialogService < Whatsapp::Providers::BaseS
|
||||
# ensuring that channels with wrong provider config wouldn't keep trying to sync templates
|
||||
whatsapp_channel.mark_message_templates_updated
|
||||
response = HTTParty.get("#{api_base_path}/configs/templates", headers: api_headers)
|
||||
whatsapp_channel.update(message_templates: response['waba_templates'], message_templates_last_updated: Time.now.utc) if response.success?
|
||||
whatsapp_channel.update!(message_templates: response['waba_templates'], message_templates_last_updated: Time.now.utc) if response.success?
|
||||
end
|
||||
|
||||
def validate_provider_config?
|
||||
|
||||
@ -30,7 +30,7 @@ class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseServi
|
||||
# ensuring that channels with wrong provider config wouldn't keep trying to sync templates
|
||||
whatsapp_channel.mark_message_templates_updated
|
||||
templates = fetch_whatsapp_templates("#{business_account_path}/message_templates?access_token=#{whatsapp_channel.provider_config['api_key']}")
|
||||
whatsapp_channel.update(message_templates: templates, message_templates_last_updated: Time.now.utc) if templates.present?
|
||||
whatsapp_channel.update!(message_templates: templates, message_templates_last_updated: Time.now.utc) if templates.present?
|
||||
end
|
||||
|
||||
def fetch_whatsapp_templates(url)
|
||||
|
||||
@ -5,7 +5,7 @@ class ArticleKeyConverter
|
||||
|
||||
def process
|
||||
new_content = replace(@article.content)
|
||||
@article.update(content: new_content)
|
||||
@article.update!(content: new_content)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -40,7 +40,7 @@ class Api::V1::Accounts::Captain::AssistantResponsesController < Api::V1::Accoun
|
||||
end
|
||||
|
||||
def destroy
|
||||
@response.destroy
|
||||
@response.destroy!
|
||||
head :no_content
|
||||
end
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ class Api::V1::Accounts::Captain::AssistantsController < Api::V1::Accounts::Base
|
||||
end
|
||||
|
||||
def destroy
|
||||
@assistant.destroy
|
||||
@assistant.destroy!
|
||||
head :no_content
|
||||
end
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ class Api::V1::Accounts::Captain::BulkActionsController < Api::V1::Accounts::Bas
|
||||
|
||||
case params[:fields][:status]
|
||||
when 'approve'
|
||||
responses.pending.update(status: 'approved')
|
||||
responses.pending.update!(status: 'approved')
|
||||
responses
|
||||
when 'delete'
|
||||
responses.destroy_all
|
||||
|
||||
@ -28,7 +28,7 @@ class Api::V1::Accounts::Captain::DocumentsController < Api::V1::Accounts::BaseC
|
||||
end
|
||||
|
||||
def destroy
|
||||
@document.destroy
|
||||
@document.destroy!
|
||||
head :no_content
|
||||
end
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ class Enterprise::Api::V1::AccountsController < Api::BaseController
|
||||
|
||||
def subscription
|
||||
if stripe_customer_id.blank? && @account.custom_attributes['is_creating_customer'].blank?
|
||||
@account.update(custom_attributes: { is_creating_customer: true })
|
||||
@account.update!(custom_attributes: { is_creating_customer: true })
|
||||
Enterprise::CreateStripeCustomerJob.perform_later(@account)
|
||||
end
|
||||
head :no_content
|
||||
|
||||
@ -6,7 +6,7 @@ module Enterprise::DeleteObjectJob
|
||||
def create_audit_entry(object, user, ip)
|
||||
return unless ['Inbox'].include?(object.class.to_s) && user.present?
|
||||
|
||||
Enterprise::AuditLog.create(
|
||||
Enterprise::AuditLog.create!(
|
||||
auditable: object,
|
||||
audited_changes: object.attributes,
|
||||
action: 'destroy',
|
||||
|
||||
@ -18,18 +18,18 @@ module Enterprise::Account::PlanUsageAndLimits
|
||||
def increment_response_usage
|
||||
current_usage = custom_attributes[CAPTAIN_RESPONSES_USAGE].to_i || 0
|
||||
custom_attributes[CAPTAIN_RESPONSES_USAGE] = current_usage + 1
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def reset_response_usage
|
||||
custom_attributes[CAPTAIN_RESPONSES_USAGE] = 0
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def update_document_usage
|
||||
# this will ensure that the document count is always accurate
|
||||
custom_attributes[CAPTAIN_DOCUMENTS_USAGE] = captain_documents.count
|
||||
save
|
||||
save!
|
||||
end
|
||||
|
||||
def subscribed_features
|
||||
|
||||
@ -19,7 +19,7 @@ module Enterprise::Audit::InboxMember
|
||||
def create_audit_log_entry(action)
|
||||
return if inbox.blank?
|
||||
|
||||
Enterprise::AuditLog.create(
|
||||
Enterprise::AuditLog.create!(
|
||||
auditable_id: id,
|
||||
auditable_type: 'InboxMember',
|
||||
action: action,
|
||||
|
||||
@ -19,7 +19,7 @@ module Enterprise::Audit::TeamMember
|
||||
def create_audit_log_entry(action)
|
||||
return if team.blank?
|
||||
|
||||
Enterprise::AuditLog.create(
|
||||
Enterprise::AuditLog.create!(
|
||||
auditable_id: id,
|
||||
auditable_type: 'TeamMember',
|
||||
action: action,
|
||||
|
||||
@ -24,7 +24,7 @@ module Enterprise::Channelable
|
||||
# skip audit log creation if the only change is whatsapp channel template update
|
||||
return if messaging_template_updates?(audited_changes)
|
||||
|
||||
Enterprise::AuditLog.create(
|
||||
Enterprise::AuditLog.create!(
|
||||
auditable_id: auditable_id,
|
||||
auditable_type: auditable_type,
|
||||
action: 'update',
|
||||
|
||||
@ -19,7 +19,7 @@ class Internal::AccountAnalysis::AccountUpdaterService
|
||||
def save_error(error_message)
|
||||
@account.internal_attributes['security_flagged'] = true
|
||||
@account.internal_attributes['security_flag_reason'] = "Error: #{error_message}"
|
||||
@account.save
|
||||
@account.save!
|
||||
end
|
||||
|
||||
def save_analysis_results(analysis)
|
||||
|
||||
@ -33,7 +33,7 @@ class ActionView::Template::Handlers::Liquid
|
||||
|
||||
def drops
|
||||
droppables = @controller.send(:liquid_droppables) if @controller.respond_to?(:liquid_droppables, true)
|
||||
droppables.update(droppables) { |_, obj| obj.try(:to_drop) || nil }
|
||||
droppables.update(droppables) { |_, obj| obj.try(:to_drop) || nil } # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
|
||||
def filters
|
||||
|
||||
@ -86,6 +86,6 @@ class ConfigLoader
|
||||
# update the existing feature flag values with default values and add new feature flags with default values
|
||||
(account_features + config.value).uniq { |h| h['name'] }
|
||||
end
|
||||
config.update({ name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS', value: features, locked: true })
|
||||
config.update!({ name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS', value: features, locked: true })
|
||||
end
|
||||
end
|
||||
|
||||
@ -9,7 +9,7 @@ class GlobalConfigService
|
||||
|
||||
return if config_value.blank?
|
||||
|
||||
i = InstallationConfig.where(name: config_key).first_or_create(value: config_value, locked: false)
|
||||
i = InstallationConfig.where(name: config_key).first_or_create!(value: config_value, locked: false)
|
||||
# To clear a nil value that might have been cached in the previous call
|
||||
GlobalConfig.clear_cache
|
||||
i.value
|
||||
|
||||
@ -9,8 +9,13 @@ class Integrations::Slack::ChannelBuilder
|
||||
channels
|
||||
end
|
||||
|
||||
def update(reference_id)
|
||||
update_reference_id(reference_id)
|
||||
def update_reference_id(reference_id)
|
||||
channel = find_channel(reference_id)
|
||||
return if channel.blank?
|
||||
|
||||
slack_client.conversations_join(channel: channel[:id]) if channel[:is_private] == false
|
||||
@hook.update!(reference_id: channel[:id], settings: { channel_name: channel[:name] }, status: 'enabled')
|
||||
@hook
|
||||
end
|
||||
|
||||
private
|
||||
@ -36,13 +41,4 @@ class Integrations::Slack::ChannelBuilder
|
||||
def find_channel(reference_id)
|
||||
channels.find { |channel| channel['id'] == reference_id }
|
||||
end
|
||||
|
||||
def update_reference_id(reference_id)
|
||||
channel = find_channel(reference_id)
|
||||
return if channel.blank?
|
||||
|
||||
slack_client.conversations_join(channel: channel[:id]) if channel[:is_private] == false
|
||||
@hook.update!(reference_id: channel[:id], settings: { channel_name: channel[:name] }, status: 'enabled')
|
||||
@hook
|
||||
end
|
||||
end
|
||||
|
||||
@ -17,7 +17,7 @@ class VapidService
|
||||
public_key = ENV.fetch('VAPID_PUBLIC_KEY') { keys.public_key }
|
||||
private_key = ENV.fetch('VAPID_PRIVATE_KEY') { keys.private_key }
|
||||
|
||||
i = InstallationConfig.where(name: 'VAPID_KEYS').first_or_create(value: { public_key: public_key, private_key: private_key })
|
||||
i = InstallationConfig.where(name: 'VAPID_KEYS').first_or_create!(value: { public_key: public_key, private_key: private_key })
|
||||
i.value
|
||||
end
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ describe NotificationBuilder do
|
||||
end
|
||||
|
||||
it 'will not create a notification if conversation contact is blocked and notification type is not conversation_mention' do
|
||||
primary_actor.contact.update(blocked: true)
|
||||
primary_actor.contact.update!(blocked: true)
|
||||
|
||||
expect do
|
||||
described_class.new(
|
||||
@ -86,7 +86,7 @@ describe NotificationBuilder do
|
||||
end
|
||||
|
||||
it 'will create a notification if conversation contact is blocked and notification type is conversation_mention' do
|
||||
primary_actor.contact.update(blocked: true)
|
||||
primary_actor.contact.update!(blocked: true)
|
||||
|
||||
expect do
|
||||
described_class.new(
|
||||
|
||||
@ -173,7 +173,7 @@ describe V2::ReportBuilder do
|
||||
conversations = account.conversations.where('created_at < ?', 1.day.ago)
|
||||
conversations.each do |conversation|
|
||||
conversation.pending!
|
||||
conversation.messages.outgoing.all.update(sender: nil)
|
||||
conversation.messages.outgoing.all.update!(sender: nil)
|
||||
end
|
||||
|
||||
perform_enqueued_jobs do
|
||||
@ -346,7 +346,7 @@ describe V2::ReportBuilder do
|
||||
end
|
||||
|
||||
it 'returns average first response time' do
|
||||
label_2.reporting_events.update(value: 1.5)
|
||||
label_2.reporting_events.update!(value: 1.5)
|
||||
|
||||
params = {
|
||||
metric: 'avg_first_response_time',
|
||||
|
||||
@ -29,7 +29,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
end
|
||||
|
||||
it 'returns custom fields on agents if present' do
|
||||
agent.update(custom_attributes: { test: 'test' })
|
||||
agent.update!(custom_attributes: { test: 'test' })
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/agents",
|
||||
headers: agent.create_new_auth_token,
|
||||
|
||||
@ -119,8 +119,8 @@ RSpec.describe 'Api::V1::Accounts::BulkActionsController', type: :request do
|
||||
end
|
||||
|
||||
it 'Bulk remove assignee id from conversations' do
|
||||
Conversation.first.update(assignee_id: agent_1.id)
|
||||
Conversation.second.update(assignee_id: agent_2.id)
|
||||
Conversation.first.update!(assignee_id: agent_1.id)
|
||||
Conversation.second.update!(assignee_id: agent_2.id)
|
||||
params = { type: 'Conversation', fields: { assignee_id: nil }, ids: Conversation.first(3).pluck(:display_id) }
|
||||
|
||||
expect(Conversation.first.status).to eq('open')
|
||||
@ -141,8 +141,8 @@ RSpec.describe 'Api::V1::Accounts::BulkActionsController', type: :request do
|
||||
end
|
||||
|
||||
it 'Do not bulk update status to nil' do
|
||||
Conversation.first.update(assignee_id: agent_1.id)
|
||||
Conversation.second.update(assignee_id: agent_2.id)
|
||||
Conversation.first.update!(assignee_id: agent_1.id)
|
||||
Conversation.second.update!(assignee_id: agent_2.id)
|
||||
params = { type: 'Conversation', fields: { status: nil }, ids: Conversation.first(3).pluck(:display_id) }
|
||||
|
||||
expect(Conversation.first.status).to eq('open')
|
||||
|
||||
@ -358,7 +358,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
end
|
||||
|
||||
it 'searches contacts using company name' do
|
||||
contact2.update(additional_attributes: { company_name: 'acme.inc' })
|
||||
contact2.update!(additional_attributes: { company_name: 'acme.inc' })
|
||||
get "/api/v1/accounts/#{account.id}/contacts/search",
|
||||
params: { q: 'acme.inc' },
|
||||
headers: admin.create_new_auth_token,
|
||||
@ -658,7 +658,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
end
|
||||
|
||||
it 'allows unblocking of contact' do
|
||||
contact.update(blocked: true)
|
||||
contact.update!(blocked: true)
|
||||
patch "/api/v1/accounts/#{account.id}/contacts/#{contact.id}",
|
||||
params: { blocked: false },
|
||||
headers: admin.create_new_auth_token,
|
||||
|
||||
@ -18,7 +18,7 @@ RSpec.describe 'Custom Filters API', type: :request do
|
||||
custom_attribute_type: ''
|
||||
}
|
||||
] }
|
||||
custom_filter.save
|
||||
custom_filter.save!
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/custom_filters' do
|
||||
|
||||
@ -318,7 +318,7 @@ RSpec.describe 'Api::V1::Accounts::MacrosController', type: :request do
|
||||
end
|
||||
|
||||
it 'Assign the agent when he is not inbox member' do
|
||||
InboxMember.last.destroy
|
||||
InboxMember.last.destroy!
|
||||
|
||||
expect(conversation.assignee).to be_nil
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ RSpec.describe 'Api::V1::Accounts::Portals', type: :request do
|
||||
end
|
||||
|
||||
it 'returns portal articles metadata' do
|
||||
portal.update(config: { allowed_locales: %w[en es], default_locale: 'en' })
|
||||
portal.update!(config: { allowed_locales: %w[en es], default_locale: 'en' })
|
||||
en_cat = create(:category, locale: :en, portal_id: portal.id, slug: 'en-cat')
|
||||
es_cat = create(:category, locale: :es, portal_id: portal.id, slug: 'es-cat')
|
||||
create(:article, category_id: en_cat.id, portal_id: portal.id, author_id: agent.id)
|
||||
|
||||
@ -119,7 +119,7 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
it 'shows an account' do
|
||||
account.update(auto_resolve_duration: 30)
|
||||
account.update!(auto_resolve_duration: 30)
|
||||
|
||||
get "/api/v1/accounts/#{account.id}",
|
||||
headers: admin.create_new_auth_token,
|
||||
@ -141,7 +141,7 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
let(:admin) { create(:user, account: account, role: :administrator) }
|
||||
|
||||
it 'returns cache_keys as expected' do
|
||||
account.update(auto_resolve_duration: 30)
|
||||
account.update!(auto_resolve_duration: 30)
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/cache_keys",
|
||||
headers: admin.create_new_auth_token,
|
||||
@ -214,7 +214,7 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
end
|
||||
|
||||
it 'updates onboarding step to invite_team if onboarding step is present in account custom attributes' do
|
||||
account.update(custom_attributes: { onboarding_step: 'account_update' })
|
||||
account.update!(custom_attributes: { onboarding_step: 'account_update' })
|
||||
put "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
|
||||
@ -205,7 +205,7 @@ RSpec.describe '/api/v1/widget/conversations/toggle_typing', type: :request do
|
||||
describe 'POST /api/v1/widget/conversations/transcript' do
|
||||
context 'with a conversation' do
|
||||
it 'sends transcript email' do
|
||||
contact.update(email: 'test@test.com')
|
||||
contact.update!(email: 'test@test.com')
|
||||
mailer = double
|
||||
allow(ConversationReplyMailer).to receive(:with).and_return(mailer)
|
||||
allow(mailer).to receive(:conversation_transcript)
|
||||
@ -217,7 +217,7 @@ RSpec.describe '/api/v1/widget/conversations/toggle_typing', type: :request do
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(mailer).to have_received(:conversation_transcript).with(conversation, 'test@test.com')
|
||||
contact.update(email: nil)
|
||||
contact.update!(email: nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -20,7 +20,7 @@ RSpec.describe Public::Api::V1::PortalsController, type: :request do
|
||||
end
|
||||
|
||||
it 'Throws unauthorised error for unknown domain' do
|
||||
portal.update(custom_domain: 'www.something.com')
|
||||
portal.update!(custom_domain: 'www.something.com')
|
||||
|
||||
get "/hc/#{portal.slug}/en"
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
params = { name: 'NewUser', email: Faker::Internet.email, role: :agent }
|
||||
|
||||
before do
|
||||
account.update(limits: { agents: 4 })
|
||||
account.update!(limits: { agents: 4 })
|
||||
create_list(:user, 4, account: account, role: :agent)
|
||||
end
|
||||
|
||||
@ -31,7 +31,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
context 'when exceeding agent limit' do
|
||||
it 'prevents creating agents and returns a payment required status' do
|
||||
# Set the limit to be less than the number of emails
|
||||
account.update(limits: { agents: 2 })
|
||||
account.update!(limits: { agents: 2 })
|
||||
|
||||
expect do
|
||||
post "/api/v1/accounts/#{account.id}/agents/bulk_create", params: bulk_create_params, headers: admin.create_new_auth_token
|
||||
@ -44,7 +44,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
|
||||
context 'when onboarding step is present in account custom attributes' do
|
||||
it 'removes onboarding step from account custom attributes' do
|
||||
account.update(custom_attributes: { onboarding_step: 'completed' })
|
||||
account.update!(custom_attributes: { onboarding_step: 'completed' })
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/agents/bulk_create", params: bulk_create_params, headers: admin.create_new_auth_token
|
||||
|
||||
|
||||
@ -116,8 +116,8 @@ RSpec.describe 'Applied SLAs API', type: :request do
|
||||
it 'returns a CSV file with breached conversations' do
|
||||
create(:applied_sla, sla_policy: sla_policy1, conversation: conversation1, sla_status: 'missed')
|
||||
create(:applied_sla, sla_policy: sla_policy1, conversation: conversation2, sla_status: 'missed')
|
||||
conversation1.update(status: 'open')
|
||||
conversation2.update(status: 'resolved')
|
||||
conversation1.update!(status: 'open')
|
||||
conversation2.update!(status: 'resolved')
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/applied_slas/download",
|
||||
headers: administrator.create_new_auth_token
|
||||
|
||||
@ -27,7 +27,7 @@ RSpec.describe 'Enterprise Conversations API', type: :request do
|
||||
end
|
||||
|
||||
it 'throws error if conversation already has a different sla' do
|
||||
conversation.update(sla_policy: create(:sla_policy, account: account))
|
||||
conversation.update!(sla_policy: create(:sla_policy, account: account))
|
||||
patch "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}",
|
||||
params: params,
|
||||
headers: agent.create_new_auth_token,
|
||||
|
||||
@ -122,8 +122,8 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
before do
|
||||
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_create(value: 'cloud')
|
||||
InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_create(value: [{ 'name': 'Hacker' }])
|
||||
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_create!(value: 'cloud')
|
||||
InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_create!(value: [{ 'name': 'Hacker' }])
|
||||
end
|
||||
|
||||
context 'when it is an agent' do
|
||||
@ -158,8 +158,8 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
|
||||
before do
|
||||
create(:conversation, account: account)
|
||||
create(:channel_api, account: account)
|
||||
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_create(value: 'cloud')
|
||||
InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_create(value: [{ 'name': 'Hacker' }])
|
||||
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_create!(value: 'cloud')
|
||||
InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_create!(value: [{ 'name': 'Hacker' }])
|
||||
end
|
||||
|
||||
it 'returns the limits if the plan is default' do
|
||||
|
||||
@ -132,7 +132,7 @@ RSpec.describe Account, type: :model do
|
||||
describe 'when limits are configured for an account' do
|
||||
before do
|
||||
create(:installation_config, name: 'CAPTAIN_CLOUD_PLAN_LIMITS', value: captain_limits.to_json)
|
||||
account.update(limits: { captain_documents: 5555, captain_responses: 9999 })
|
||||
account.update!(limits: { captain_documents: 5555, captain_responses: 9999 })
|
||||
end
|
||||
|
||||
it 'returns limits based on custom attributes' do
|
||||
@ -149,7 +149,7 @@ RSpec.describe Account, type: :model do
|
||||
end
|
||||
|
||||
it 'creates audit logs when account is updated' do
|
||||
account.update(name: 'New Name')
|
||||
account.update!(name: 'New Name')
|
||||
expect(Audited::Audit.where(auditable_type: 'Account', action: 'update').count).to eq 1
|
||||
end
|
||||
end
|
||||
@ -159,23 +159,23 @@ RSpec.describe Account, type: :model do
|
||||
end
|
||||
|
||||
it 'returns max limits from account when enterprise version' do
|
||||
account.update(limits: { agents: 10 })
|
||||
account.update!(limits: { agents: 10 })
|
||||
expect(account.usage_limits[:agents]).to eq(10)
|
||||
end
|
||||
|
||||
it 'returns limits based on subscription' do
|
||||
account.update(limits: { agents: 10 }, custom_attributes: { subscribed_quantity: 5 })
|
||||
account.update!(limits: { agents: 10 }, custom_attributes: { subscribed_quantity: 5 })
|
||||
expect(account.usage_limits[:agents]).to eq(5)
|
||||
end
|
||||
|
||||
it 'returns max limits from global config if account limit is absent' do
|
||||
account.update(limits: { agents: '' })
|
||||
account.update!(limits: { agents: '' })
|
||||
expect(account.usage_limits[:agents]).to eq(20)
|
||||
end
|
||||
|
||||
it 'returns max limits from app limit if account limit and installation config is absent' do
|
||||
account.update(limits: { agents: '' })
|
||||
InstallationConfig.where(name: 'ACCOUNT_AGENTS_LIMIT').update(value: '')
|
||||
account.update!(limits: { agents: '' })
|
||||
InstallationConfig.where(name: 'ACCOUNT_AGENTS_LIMIT').update!(value: '')
|
||||
|
||||
expect(account.usage_limits[:agents]).to eq(ChatwootApp.max_limit)
|
||||
end
|
||||
|
||||
@ -14,7 +14,7 @@ RSpec.describe AutomationRule do
|
||||
|
||||
context 'when automation rule is updated' do
|
||||
it 'has associated audit log created' do
|
||||
automation_rule.update(name: 'automation rule 2')
|
||||
automation_rule.update!(name: 'automation rule 2')
|
||||
expect(Audited::Audit.where(auditable_type: 'AutomationRule', action: 'update').count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -21,7 +21,7 @@ RSpec.describe InboxMember, type: :model do
|
||||
|
||||
context 'when inbox member is destroyed' do
|
||||
it 'has associated audit log created' do
|
||||
inbox_member.destroy
|
||||
inbox_member.destroy!
|
||||
audit_log = Audited::Audit.find_by(auditable: inbox_member, action: 'destroy')
|
||||
expect(audit_log).to be_present
|
||||
expect(audit_log.audited_changes['inbox_id']).to eq(inbox.id)
|
||||
|
||||
@ -28,7 +28,7 @@ RSpec.describe Inbox do
|
||||
|
||||
it 'returns member ids with assignment capacity with inbox max_assignment_limit is configured' do
|
||||
# agent 1 has 1 conversations, agent 2 has 2 conversations, agent 3 has 3 conversations and agent 4 with none
|
||||
inbox.update(auto_assignment_config: { max_assignment_limit: 2 })
|
||||
inbox.update!(auto_assignment_config: { max_assignment_limit: 2 })
|
||||
expect(inbox.member_ids_with_assignment_capacity).to contain_exactly(inbox_member_1.user_id, inbox_member_4.user_id)
|
||||
end
|
||||
|
||||
@ -46,7 +46,7 @@ RSpec.describe Inbox do
|
||||
|
||||
context 'when inbox is updated' do
|
||||
it 'has associated audit log created' do
|
||||
inbox.update(name: 'Updated Inbox')
|
||||
inbox.update!(name: 'Updated Inbox')
|
||||
expect(Audited::Audit.where(auditable_type: 'Inbox', action: 'update').count).to eq(1)
|
||||
end
|
||||
end
|
||||
@ -55,7 +55,7 @@ RSpec.describe Inbox do
|
||||
it 'has associated audit log created' do
|
||||
previous_color = inbox.channel.widget_color
|
||||
new_color = '#ff0000'
|
||||
inbox.channel.update(widget_color: new_color)
|
||||
inbox.channel.update!(widget_color: new_color)
|
||||
|
||||
# check if channel update creates an audit log against inbox
|
||||
expect(Audited::Audit.where(auditable_type: 'Inbox', action: 'update').count).to eq(1)
|
||||
@ -78,7 +78,7 @@ RSpec.describe Inbox do
|
||||
|
||||
context 'when inbox is updated' do
|
||||
it 'has associated audit log created' do
|
||||
inbox.update(name: 'Updated Inbox')
|
||||
inbox.update!(name: 'Updated Inbox')
|
||||
expect(Audited::Audit.where(auditable_type: 'Inbox', action: 'update').count).to eq(1)
|
||||
end
|
||||
end
|
||||
@ -87,7 +87,7 @@ RSpec.describe Inbox do
|
||||
it 'has associated audit log created' do
|
||||
previous_webhook = inbox.channel.webhook_url
|
||||
new_webhook = 'https://example2.com'
|
||||
inbox.channel.update(webhook_url: new_webhook)
|
||||
inbox.channel.update!(webhook_url: new_webhook)
|
||||
|
||||
# check if channel update creates an audit log against inbox
|
||||
expect(Audited::Audit.where(auditable_type: 'Inbox', action: 'update').count).to eq(1)
|
||||
@ -122,7 +122,7 @@ RSpec.describe Inbox do
|
||||
|
||||
context 'when inbox is updated' do
|
||||
it 'has associated audit log created' do
|
||||
inbox.update(name: 'Updated Inbox')
|
||||
inbox.update!(name: 'Updated Inbox')
|
||||
expect(Audited::Audit.where(auditable_type: 'Inbox', action: 'update').count).to eq(1)
|
||||
end
|
||||
end
|
||||
@ -131,7 +131,7 @@ RSpec.describe Inbox do
|
||||
it 'has associated audit log created' do
|
||||
previous_phone_number = inbox.channel.phone_number
|
||||
new_phone_number = '1234567890'
|
||||
inbox.channel.update(phone_number: new_phone_number)
|
||||
inbox.channel.update!(phone_number: new_phone_number)
|
||||
|
||||
# check if channel update creates an audit log against inbox
|
||||
expect(Audited::Audit.where(auditable_type: 'Inbox', action: 'update').count).to eq(1)
|
||||
|
||||
@ -15,7 +15,7 @@ RSpec.describe Macro do
|
||||
|
||||
context 'when macro is updated' do
|
||||
it 'has associated audit log created' do
|
||||
macro.update(name: 'awesome macro')
|
||||
macro.update!(name: 'awesome macro')
|
||||
expect(Audited::Audit.where(auditable_type: 'Macro', action: 'update').count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -21,7 +21,7 @@ RSpec.describe TeamMember, type: :model do
|
||||
|
||||
context 'when team member is destroyed' do
|
||||
it 'has associated audit log created' do
|
||||
team_member.destroy
|
||||
team_member.destroy!
|
||||
audit_log = Audited::Audit.find_by(auditable: team_member, action: 'destroy')
|
||||
expect(audit_log).to be_present
|
||||
expect(audit_log.audited_changes['team_id']).to eq(team.id)
|
||||
|
||||
@ -15,7 +15,7 @@ RSpec.describe Team do
|
||||
|
||||
context 'when team is updated' do
|
||||
it 'has associated audit log created' do
|
||||
team.update(description: 'awesome team')
|
||||
team.update!(description: 'awesome team')
|
||||
expect(Audited::Audit.where(auditable_type: 'Team', action: 'update').count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -35,7 +35,7 @@ RSpec.describe User do
|
||||
|
||||
it 'will not add error when trying to update a existing user' do
|
||||
allow(ChatwootHub).to receive(:pricing_plan_quantity).and_return(1)
|
||||
existing_user.update(name: 'new name')
|
||||
existing_user.update!(name: 'new name')
|
||||
# since there is user and existing user, we are already over limits
|
||||
existing_user.valid?
|
||||
expect(existing_user.errors[:base]).to be_empty
|
||||
|
||||
@ -15,7 +15,7 @@ RSpec.describe Webhook do
|
||||
|
||||
context 'when webhook is updated' do
|
||||
it 'has associated audit log created' do
|
||||
webhook.update(url: 'https://example.com')
|
||||
webhook.update!(url: 'https://example.com')
|
||||
expect(Audited::Audit.where(auditable_type: 'Webhook', action: 'update').count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -60,7 +60,7 @@ RSpec.describe Enterprise::Conversations::PermissionFilterService do
|
||||
# Create custom role with conversation_manage permission
|
||||
test_custom_role = create(:custom_role, account: test_account, permissions: ['conversation_manage'])
|
||||
account_user = AccountUser.find_by(user: test_agent, account: test_account)
|
||||
account_user.update(role: :agent, custom_role: test_custom_role)
|
||||
account_user.update!(role: :agent, custom_role: test_custom_role)
|
||||
|
||||
# Create some conversations
|
||||
assigned_conversation = create(:conversation, account: test_account, inbox: test_inbox, assignee: test_agent)
|
||||
@ -96,7 +96,7 @@ RSpec.describe Enterprise::Conversations::PermissionFilterService do
|
||||
test_custom_role = create(:custom_role, account: test_account, permissions: %w[conversation_participating_manage])
|
||||
|
||||
account_user = AccountUser.find_by(user: test_agent, account: test_account)
|
||||
account_user.update(role: :agent, custom_role: test_custom_role)
|
||||
account_user.update!(role: :agent, custom_role: test_custom_role)
|
||||
|
||||
# Create some conversations
|
||||
other_conversation = create(:conversation, account: test_account, inbox: test_inbox)
|
||||
@ -131,7 +131,7 @@ RSpec.describe Enterprise::Conversations::PermissionFilterService do
|
||||
test_custom_role = create(:custom_role, account: test_account, permissions: %w[conversation_unassigned_manage])
|
||||
|
||||
account_user = AccountUser.find_by(user: test_agent, account: test_account)
|
||||
account_user.update(role: :agent, custom_role: test_custom_role)
|
||||
account_user.update!(role: :agent, custom_role: test_custom_role)
|
||||
|
||||
# Create some conversations
|
||||
assigned_conversation = create(:conversation, account: test_account, inbox: test_inbox, assignee: test_agent)
|
||||
@ -170,7 +170,7 @@ RSpec.describe Enterprise::Conversations::PermissionFilterService do
|
||||
test_custom_role = create(:custom_role, account: test_account, permissions: permissions)
|
||||
|
||||
account_user = AccountUser.find_by(user: test_agent, account: test_account)
|
||||
account_user.update(role: :agent, custom_role: test_custom_role)
|
||||
account_user.update!(role: :agent, custom_role: test_custom_role)
|
||||
|
||||
# Create some conversations
|
||||
assigned_to_agent = create(:conversation, account: test_account, inbox: test_inbox, assignee: test_agent)
|
||||
|
||||
@ -42,8 +42,8 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
|
||||
context 'when next response SLA is missed' do
|
||||
before do
|
||||
applied_sla.sla_policy.update(next_response_time_threshold: 1.hour)
|
||||
conversation.update(first_reply_created_at: 5.hours.ago, waiting_since: 5.hours.ago)
|
||||
applied_sla.sla_policy.update!(next_response_time_threshold: 1.hour)
|
||||
conversation.update!(first_reply_created_at: 5.hours.ago, waiting_since: 5.hours.ago)
|
||||
end
|
||||
|
||||
it 'updates the SLA status to missed and logs a warning' do
|
||||
@ -89,7 +89,7 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
context 'when resolved conversation with resolution time SLA is missed' do
|
||||
before do
|
||||
conversation.resolved!
|
||||
applied_sla.sla_policy.update(resolution_time_threshold: 1.hour)
|
||||
applied_sla.sla_policy.update!(resolution_time_threshold: 1.hour)
|
||||
end
|
||||
|
||||
it 'does not update the SLA status to missed' do
|
||||
@ -100,8 +100,8 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
|
||||
context 'when multiple SLAs are missed' do
|
||||
before do
|
||||
applied_sla.sla_policy.update(first_response_time_threshold: 1.hour, next_response_time_threshold: 1.hour, resolution_time_threshold: 1.hour)
|
||||
conversation.update(first_reply_created_at: 5.hours.ago, waiting_since: 5.hours.ago)
|
||||
applied_sla.sla_policy.update!(first_response_time_threshold: 1.hour, next_response_time_threshold: 1.hour, resolution_time_threshold: 1.hour)
|
||||
conversation.update!(first_reply_created_at: 5.hours.ago, waiting_since: 5.hours.ago)
|
||||
end
|
||||
|
||||
it 'updates the SLA status to missed and logs multiple warnings' do
|
||||
@ -119,8 +119,8 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
describe '#perform - SLA hits' do
|
||||
context 'when first response SLA is hit' do
|
||||
before do
|
||||
applied_sla.sla_policy.update(first_response_time_threshold: 6.hours)
|
||||
conversation.update(first_reply_created_at: 30.minutes.ago)
|
||||
applied_sla.sla_policy.update!(first_response_time_threshold: 6.hours)
|
||||
conversation.update!(first_reply_created_at: 30.minutes.ago)
|
||||
end
|
||||
|
||||
it 'sla remains active until conversation is resolved' do
|
||||
@ -142,8 +142,8 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
|
||||
context 'when next response SLA is hit' do
|
||||
before do
|
||||
applied_sla.sla_policy.update(next_response_time_threshold: 6.hours)
|
||||
conversation.update(first_reply_created_at: 30.minutes.ago, waiting_since: nil)
|
||||
applied_sla.sla_policy.update!(next_response_time_threshold: 6.hours)
|
||||
conversation.update!(first_reply_created_at: 30.minutes.ago, waiting_since: nil)
|
||||
end
|
||||
|
||||
it 'sla remains active until conversation is resolved' do
|
||||
@ -164,7 +164,7 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
|
||||
context 'when resolution time SLA is hit' do
|
||||
before do
|
||||
applied_sla.sla_policy.update(resolution_time_threshold: 8.hours)
|
||||
applied_sla.sla_policy.update!(resolution_time_threshold: 8.hours)
|
||||
conversation.resolved!
|
||||
end
|
||||
|
||||
@ -182,7 +182,7 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
describe 'SLA evaluation with frt hit, multiple nrt misses and rt miss' do
|
||||
before do
|
||||
# Setup SLA Policy thresholds
|
||||
applied_sla.sla_policy.update(
|
||||
applied_sla.sla_policy.update!(
|
||||
first_response_time_threshold: 2.hours, # Hit frt
|
||||
next_response_time_threshold: 1.hour, # Miss nrt multiple times
|
||||
resolution_time_threshold: 4.hours # Miss rt
|
||||
@ -204,7 +204,7 @@ RSpec.describe Sla::EvaluateAppliedSlaService do
|
||||
described_class.new(applied_sla: applied_sla).perform
|
||||
|
||||
# Conversation is resolved missing rt
|
||||
conversation.update(status: 'resolved')
|
||||
conversation.update!(status: 'resolved')
|
||||
|
||||
# this will not create a new notification for rt miss as conversation is resolved
|
||||
# but we would have already created an rt miss notification during previous evaluation
|
||||
|
||||
@ -9,7 +9,7 @@ describe EmailChannelFinder do
|
||||
let(:reply_cc_mail) { create_inbound_email_from_fixture('reply_cc.eml') }
|
||||
|
||||
it 'return channel with cc email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
channel = described_class.new(reply_cc_mail.mail).perform
|
||||
expect(channel).to eq(channel_email)
|
||||
end
|
||||
@ -19,21 +19,21 @@ describe EmailChannelFinder do
|
||||
let(:reply_mail) { create_inbound_email_from_fixture('reply.eml') }
|
||||
|
||||
it 'return channel with to email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
reply_mail.mail['to'] = 'test@example.com'
|
||||
channel = described_class.new(reply_mail.mail).perform
|
||||
expect(channel).to eq(channel_email)
|
||||
end
|
||||
|
||||
it 'return channel with to+extension email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
reply_mail.mail['to'] = 'test+123@example.com'
|
||||
channel = described_class.new(reply_mail.mail).perform
|
||||
expect(channel).to eq(channel_email)
|
||||
end
|
||||
|
||||
it 'return channel with cc email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
reply_mail.mail['to'] = nil
|
||||
reply_mail.mail['cc'] = 'test@example.com'
|
||||
channel = described_class.new(reply_mail.mail).perform
|
||||
@ -41,7 +41,7 @@ describe EmailChannelFinder do
|
||||
end
|
||||
|
||||
it 'return channel with bcc email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
reply_mail.mail['to'] = nil
|
||||
reply_mail.mail['bcc'] = 'test@example.com'
|
||||
channel = described_class.new(reply_mail.mail).perform
|
||||
@ -49,7 +49,7 @@ describe EmailChannelFinder do
|
||||
end
|
||||
|
||||
it 'return channel with X-Original-To email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
reply_mail.mail['to'] = nil
|
||||
reply_mail.mail['X-Original-To'] = 'test@example.com'
|
||||
channel = described_class.new(reply_mail.mail).perform
|
||||
|
||||
@ -11,7 +11,7 @@ RSpec.describe Account::ConversationsResolutionSchedulerJob do
|
||||
end
|
||||
|
||||
it 'enqueues Conversations::ResolutionJob' do
|
||||
account.update(auto_resolve_duration: 10)
|
||||
account.update!(auto_resolve_duration: 10)
|
||||
expect(Conversations::ResolutionJob).to receive(:perform_later).with(account: account).once
|
||||
described_class.perform_now
|
||||
end
|
||||
|
||||
@ -18,15 +18,15 @@ RSpec.describe Conversations::ResolutionJob do
|
||||
end
|
||||
|
||||
it 'resolves the issue if time of inactivity is more than the auto resolve duration' do
|
||||
account.update(auto_resolve_duration: 10)
|
||||
conversation.update(last_activity_at: 13.days.ago)
|
||||
account.update!(auto_resolve_duration: 10)
|
||||
conversation.update!(last_activity_at: 13.days.ago)
|
||||
described_class.perform_now(account: account)
|
||||
expect(conversation.reload.status).to eq('resolved')
|
||||
end
|
||||
|
||||
it 'resolved only a limited number of conversations in a single execution' do
|
||||
stub_const('Limits::BULK_ACTIONS_LIMIT', 2)
|
||||
account.update(auto_resolve_duration: 10)
|
||||
account.update!(auto_resolve_duration: 10)
|
||||
create_list(:conversation, 3, account: account, last_activity_at: 13.days.ago)
|
||||
described_class.perform_now(account: account)
|
||||
expect(account.conversations.resolved.count).to eq(Limits::BULK_ACTIONS_LIMIT)
|
||||
|
||||
@ -102,7 +102,7 @@ RSpec.describe Webhooks::WhatsappEventsJob do
|
||||
context 'when default provider' do
|
||||
it 'enqueue Whatsapp::IncomingMessageService' do
|
||||
stub_request(:post, 'https://waba.360dialog.io/v1/configs/webhook')
|
||||
channel.update(provider: 'default')
|
||||
channel.update!(provider: 'default')
|
||||
allow(Whatsapp::IncomingMessageService).to receive(:new).and_return(process_service)
|
||||
expect(Whatsapp::IncomingMessageService).to receive(:new)
|
||||
job.perform_now(params)
|
||||
|
||||
@ -157,7 +157,7 @@ describe Integrations::Dialogflow::ProcessorService do
|
||||
let(:processor) { described_class.new(event_name: event_name, hook: hook, event_data: event_data) }
|
||||
|
||||
before do
|
||||
hook.update(settings: { 'project_id' => 'test', 'credentials' => 'creds' })
|
||||
hook.update(settings: { 'project_id' => 'test', 'credentials' => 'creds' }) # rubocop:disable Rails/SaveBang
|
||||
allow(google_dialogflow).to receive(:new).and_return(session_client)
|
||||
allow(session_client).to receive(:detect_intent).and_return({ session: session, query_input: query_input })
|
||||
end
|
||||
|
||||
@ -46,7 +46,7 @@ describe Integrations::Facebook::DeliveryStatus do
|
||||
end
|
||||
|
||||
it 'does not update the message status if the message was created after the watermark' do
|
||||
message1.update(created_at: 1.day.from_now)
|
||||
message1.update!(created_at: 1.day.from_now)
|
||||
message_deliveries.delivery['watermark'] = 1.day.ago.to_i
|
||||
described_class.new(params: message_deliveries).perform
|
||||
expect(message1.reload.status).to eq('sent')
|
||||
@ -73,7 +73,7 @@ describe Integrations::Facebook::DeliveryStatus do
|
||||
end
|
||||
|
||||
it 'does not update the message status if the message was created after the watermark' do
|
||||
message1.update(created_at: 1.day.from_now)
|
||||
message1.update!(created_at: 1.day.from_now)
|
||||
message_reads.read['watermark'] = 1.day.ago.to_i
|
||||
described_class.new(params: message_reads).perform
|
||||
expect(message1.reload.status).to eq('sent')
|
||||
|
||||
@ -18,7 +18,7 @@ describe OnlineStatusTracker do
|
||||
end
|
||||
|
||||
it 'returns agents who have auto offline configured false' do
|
||||
user2.account_users.first.update(auto_offline: false)
|
||||
user2.account_users.first.update!(auto_offline: false)
|
||||
expect(described_class.get_available_users(account.id).keys).to contain_exactly(user1.id.to_s, user2.id.to_s)
|
||||
end
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ describe ActionCableListener do
|
||||
it 'sends message to all hmac verified contact inboxes' do
|
||||
# HACK: to reload conversation inbox members
|
||||
expect(conversation.inbox.reload.inbox_members.count).to eq(1)
|
||||
conversation.contact_inbox.update(hmac_verified: true)
|
||||
conversation.contact_inbox.update!(hmac_verified: true)
|
||||
# creating a non verified contact inbox to ensure the events are not sent to it
|
||||
create(:contact_inbox, contact: conversation.contact, inbox: inbox)
|
||||
verified_contact_inbox = create(:contact_inbox, contact: conversation.contact, inbox: inbox, hmac_verified: true)
|
||||
|
||||
@ -331,7 +331,7 @@ describe AutomationRuleListener do
|
||||
}.with_indifferent_access
|
||||
]
|
||||
)
|
||||
conversation.update(status: :snoozed)
|
||||
conversation.update!(status: :snoozed)
|
||||
end
|
||||
|
||||
let!(:event) do
|
||||
@ -351,7 +351,7 @@ describe AutomationRuleListener do
|
||||
end
|
||||
|
||||
it 'triggers automation rule to assign team with OR operator' do
|
||||
conversation.update(status: :open)
|
||||
conversation.update!(status: :open)
|
||||
automation_rule.update!(
|
||||
conditions: [
|
||||
{
|
||||
@ -380,7 +380,7 @@ describe AutomationRuleListener do
|
||||
|
||||
context 'when rule doesnt match' do
|
||||
it 'when automation rule is triggered it will not assign team' do
|
||||
conversation.update(status: :open)
|
||||
conversation.update!(status: :open)
|
||||
|
||||
expect(conversation.team_id).not_to eq(team.id)
|
||||
|
||||
@ -391,7 +391,7 @@ describe AutomationRuleListener do
|
||||
end
|
||||
|
||||
it 'when automation rule is triggers, it will not assign team on attribute_changed values' do
|
||||
conversation.update(status: :snoozed)
|
||||
conversation.update!(status: :snoozed)
|
||||
event = Events::Base.new('conversation_updated', Time.zone.now, { conversation: conversation,
|
||||
changed_attributes: { company: %w[Marvel DC] } })
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ describe NotificationListener do
|
||||
|
||||
it 'will not create duplicate new message notification for the same user for mentions participation & assignment' do
|
||||
create(:inbox_member, user: first_agent, inbox: inbox)
|
||||
conversation.update(assignee: first_agent)
|
||||
conversation.update!(assignee: first_agent)
|
||||
|
||||
message = build(
|
||||
:message,
|
||||
@ -144,9 +144,9 @@ describe NotificationListener do
|
||||
|
||||
it 'will not create duplicate new message notifications for assignment & participation' do
|
||||
create(:inbox_member, user: first_agent, inbox: inbox)
|
||||
conversation.update(assignee: first_agent)
|
||||
conversation.update!(assignee: first_agent)
|
||||
# participants is created by async job. so creating it directly for testcase
|
||||
conversation.conversation_participants.first_or_create(user: first_agent)
|
||||
conversation.conversation_participants.first_or_create!(user: first_agent)
|
||||
|
||||
message = build(
|
||||
:message,
|
||||
|
||||
@ -50,7 +50,7 @@ describe ReportingEventListener do
|
||||
end
|
||||
|
||||
it 'does not create a conversation_bot_resolved event if resolved conversation inbox does not have active bot' do
|
||||
bot_resolved_conversation.update(inbox: inbox)
|
||||
bot_resolved_conversation.update!(inbox: inbox)
|
||||
event = Events::Base.new('conversation.resolved', Time.zone.now, conversation: bot_resolved_conversation)
|
||||
listener.conversation_resolved(event)
|
||||
expect(account.reporting_events.where(name: 'conversation_bot_resolved').count).to be 0
|
||||
|
||||
@ -166,7 +166,7 @@ describe WebhookListener do
|
||||
it 'triggers webhook' do
|
||||
webhook = create(:webhook, inbox: inbox, account: account)
|
||||
|
||||
conversation.update(custom_attributes: { test: 'testing custom attri webhook' })
|
||||
conversation.update!(custom_attributes: { test: 'testing custom attri webhook' })
|
||||
|
||||
expect(WebhookJob).to receive(:perform_later).with(
|
||||
webhook.url,
|
||||
|
||||
@ -43,7 +43,7 @@ RSpec.describe ApplicationMailbox do
|
||||
|
||||
it 'routes support emails to Support Mailbox when mail is to channel email' do
|
||||
# this email is hardcoded in the support.eml, that's why we are updating this
|
||||
channel_email.update(email: 'care@example.com')
|
||||
channel_email.update!(email: 'care@example.com')
|
||||
dbl = double
|
||||
expect(SupportMailbox).to receive(:new).and_return(dbl)
|
||||
expect(dbl).to receive(:perform_processing).and_return(true)
|
||||
@ -52,7 +52,7 @@ RSpec.describe ApplicationMailbox do
|
||||
|
||||
it 'routes support emails to Support Mailbox when mail is to channel forward to email' do
|
||||
# this email is hardcoded in the support.eml, that's why we are updating this
|
||||
channel_email.update(forward_to_email: 'care@example.com')
|
||||
channel_email.update!(forward_to_email: 'care@example.com')
|
||||
dbl = double
|
||||
expect(SupportMailbox).to receive(:new).and_return(dbl)
|
||||
expect(dbl).to receive(:perform_processing).and_return(true)
|
||||
@ -60,7 +60,7 @@ RSpec.describe ApplicationMailbox do
|
||||
end
|
||||
|
||||
it 'routes support emails to Support Mailbox with cc email' do
|
||||
channel_email.update(email: 'test@example.com')
|
||||
channel_email.update!(email: 'test@example.com')
|
||||
dbl = double
|
||||
expect(SupportMailbox).to receive(:new).and_return(dbl)
|
||||
expect(dbl).to receive(:perform_processing).and_return(true)
|
||||
|
||||
@ -71,7 +71,7 @@ RSpec.describe ConversationReplyMailer do
|
||||
|
||||
it 'will not send email if conversation is already viewed by contact' do
|
||||
create(:message, message_type: 'outgoing', account: account, conversation: conversation)
|
||||
conversation.update(contact_last_seen_at: Time.zone.now)
|
||||
conversation.update!(contact_last_seen_at: Time.zone.now)
|
||||
expect(mail).to be_nil
|
||||
end
|
||||
|
||||
@ -132,7 +132,7 @@ RSpec.describe ConversationReplyMailer do
|
||||
|
||||
it 'will not send email if conversation is already viewed by contact' do
|
||||
create(:message, message_type: 'outgoing', account: account, conversation: conversation)
|
||||
conversation.update(contact_last_seen_at: Time.zone.now)
|
||||
conversation.update!(contact_last_seen_at: Time.zone.now)
|
||||
expect(mail).to be_nil
|
||||
end
|
||||
end
|
||||
@ -176,20 +176,20 @@ RSpec.describe ConversationReplyMailer do
|
||||
end
|
||||
|
||||
it 'renders sender name even when assignee is not present' do
|
||||
conversation.update(assignee_id: nil)
|
||||
conversation.update!(assignee_id: nil)
|
||||
mail = described_class.email_reply(message)
|
||||
expect(mail['from'].value).to eq "#{message.sender.available_name} from #{smtp_email_channel.inbox.name} <#{smtp_email_channel.email}>"
|
||||
end
|
||||
|
||||
it 'renders assignee name in the from address when sender_name not available' do
|
||||
message.update(sender_id: nil)
|
||||
message.update!(sender_id: nil)
|
||||
mail = described_class.email_reply(message)
|
||||
expect(mail['from'].value).to eq "#{conversation.assignee.available_name} from #{smtp_email_channel.inbox.name} <#{smtp_email_channel.email}>"
|
||||
end
|
||||
|
||||
it 'renders inbox name as sender and assignee or business_name not present' do
|
||||
message.update(sender_id: nil)
|
||||
conversation.update(assignee_id: nil)
|
||||
message.update!(sender_id: nil)
|
||||
conversation.update!(assignee_id: nil)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
expect(mail['from'].value).to eq "Notifications from #{smtp_email_channel.inbox.name} <#{smtp_email_channel.email}>"
|
||||
@ -197,14 +197,14 @@ RSpec.describe ConversationReplyMailer do
|
||||
|
||||
context 'when friendly name enabled' do
|
||||
before do
|
||||
conversation.inbox.update(sender_name_type: 0)
|
||||
conversation.inbox.update(business_name: 'Business Name')
|
||||
conversation.inbox.update!(sender_name_type: 0)
|
||||
conversation.inbox.update!(business_name: 'Business Name')
|
||||
end
|
||||
|
||||
it 'renders sender name as sender and assignee and business_name not present' do
|
||||
message.update(sender_id: nil)
|
||||
conversation.update(assignee_id: nil)
|
||||
conversation.inbox.update(business_name: nil)
|
||||
message.update!(sender_id: nil)
|
||||
conversation.update!(assignee_id: nil)
|
||||
conversation.inbox.update!(business_name: nil)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
|
||||
@ -212,8 +212,8 @@ RSpec.describe ConversationReplyMailer do
|
||||
end
|
||||
|
||||
it 'renders sender name as sender and assignee nil and business_name present' do
|
||||
message.update(sender_id: nil)
|
||||
conversation.update(assignee_id: nil)
|
||||
message.update!(sender_id: nil)
|
||||
conversation.update!(assignee_id: nil)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
|
||||
@ -223,8 +223,8 @@ RSpec.describe ConversationReplyMailer do
|
||||
end
|
||||
|
||||
it 'renders sender name as sender nil and assignee and business_name present' do
|
||||
message.update(sender_id: nil)
|
||||
conversation.update(assignee_id: agent.id)
|
||||
message.update!(sender_id: nil)
|
||||
conversation.update!(assignee_id: agent.id)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
expect(mail['from'].value).to eq "#{agent.available_name} from #{conversation.inbox.business_name} <#{smtp_email_channel.email}>"
|
||||
@ -232,8 +232,8 @@ RSpec.describe ConversationReplyMailer do
|
||||
|
||||
it 'renders sender name as sender and assignee and business_name present' do
|
||||
agent_2 = create(:user, email: 'agent2@example.com', account: account)
|
||||
message.update(sender_id: agent_2.id)
|
||||
conversation.update(assignee_id: agent.id)
|
||||
message.update!(sender_id: agent_2.id)
|
||||
conversation.update!(assignee_id: agent.id)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
expect(mail['from'].value).to eq "#{agent_2.available_name} from #{conversation.inbox.business_name} <#{smtp_email_channel.email}>"
|
||||
@ -242,14 +242,14 @@ RSpec.describe ConversationReplyMailer do
|
||||
|
||||
context 'when friendly name disabled' do
|
||||
before do
|
||||
conversation.inbox.update(sender_name_type: 1)
|
||||
conversation.inbox.update(business_name: 'Business Name')
|
||||
conversation.inbox.update!(sender_name_type: 1)
|
||||
conversation.inbox.update!(business_name: 'Business Name')
|
||||
end
|
||||
|
||||
it 'renders sender name as business_name not present' do
|
||||
message.update(sender_id: nil)
|
||||
conversation.update(assignee_id: nil)
|
||||
conversation.inbox.update(business_name: nil)
|
||||
message.update!(sender_id: nil)
|
||||
conversation.update!(assignee_id: nil)
|
||||
conversation.inbox.update!(business_name: nil)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
|
||||
@ -257,8 +257,8 @@ RSpec.describe ConversationReplyMailer do
|
||||
end
|
||||
|
||||
it 'renders sender name as business_name present' do
|
||||
message.update(sender_id: nil)
|
||||
conversation.update(assignee_id: nil)
|
||||
message.update!(sender_id: nil)
|
||||
conversation.update!(assignee_id: nil)
|
||||
|
||||
mail = described_class.email_reply(message)
|
||||
|
||||
|
||||
@ -52,21 +52,21 @@ RSpec.describe Account do
|
||||
let(:account) { create(:account) }
|
||||
|
||||
it 'returns the domain from inbox if inbox value is present' do
|
||||
account.update(domain: 'test.com')
|
||||
account.update!(domain: 'test.com')
|
||||
with_modified_env MAILER_INBOUND_EMAIL_DOMAIN: 'test2.com' do
|
||||
expect(account.inbound_email_domain).to eq('test.com')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the domain from ENV if inbox value is nil' do
|
||||
account.update(domain: nil)
|
||||
account.update!(domain: nil)
|
||||
with_modified_env MAILER_INBOUND_EMAIL_DOMAIN: 'test.com' do
|
||||
expect(account.inbound_email_domain).to eq('test.com')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the domain from ENV if inbox value is empty string' do
|
||||
account.update(domain: '')
|
||||
account.update!(domain: '')
|
||||
with_modified_env MAILER_INBOUND_EMAIL_DOMAIN: 'test.com' do
|
||||
expect(account.inbound_email_domain).to eq('test.com')
|
||||
end
|
||||
@ -77,21 +77,21 @@ RSpec.describe Account do
|
||||
let(:account) { create(:account) }
|
||||
|
||||
it 'returns the support email from inbox if inbox value is present' do
|
||||
account.update(support_email: 'support@chatwoot.com')
|
||||
account.update!(support_email: 'support@chatwoot.com')
|
||||
with_modified_env MAILER_SENDER_EMAIL: 'hello@chatwoot.com' do
|
||||
expect(account.support_email).to eq('support@chatwoot.com')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the support email from ENV if inbox value is nil' do
|
||||
account.update(support_email: nil)
|
||||
account.update!(support_email: nil)
|
||||
with_modified_env MAILER_SENDER_EMAIL: 'hello@chatwoot.com' do
|
||||
expect(account.support_email).to eq('hello@chatwoot.com')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the support email from ENV if inbox value is empty string' do
|
||||
account.update(support_email: '')
|
||||
account.update!(support_email: '')
|
||||
with_modified_env MAILER_SENDER_EMAIL: 'hello@chatwoot.com' do
|
||||
expect(account.support_email).to eq('hello@chatwoot.com')
|
||||
end
|
||||
@ -104,7 +104,7 @@ RSpec.describe Account do
|
||||
query = "select * from information_schema.sequences where sequence_name in ('camp_dpid_seq_#{account.id}', 'conv_dpid_seq_#{account.id}');"
|
||||
expect(ActiveRecord::Base.connection.execute(query).count).to eq(2)
|
||||
expect(account.locale).to eq('en')
|
||||
account.destroy
|
||||
account.destroy!
|
||||
expect(ActiveRecord::Base.connection.execute(query).count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
@ -23,7 +23,7 @@ RSpec.describe Category do
|
||||
it 'returns erros when locale is not allowed in the portal' do
|
||||
category = create(:category, slug: 'category_1', locale: 'en', portal_id: portal.id)
|
||||
expect(category).to be_valid
|
||||
category.update(locale: 'es')
|
||||
expect(category.update(locale: 'es')).to be(false)
|
||||
expect(category.errors.full_messages[0]).to eq("Locale es of category is not part of portal's [\"en\"].")
|
||||
end
|
||||
end
|
||||
|
||||
@ -65,7 +65,7 @@ RSpec.describe Channel::TwilioSms do
|
||||
end
|
||||
|
||||
it 'sends via twilio client' do
|
||||
expect(twilio_messages).to receive(:create).with(
|
||||
expect(twilio_messages).to receive(:create!).with(
|
||||
messaging_service_sid: channel.messaging_service_sid,
|
||||
to: '+15555550111',
|
||||
body: 'hello world',
|
||||
@ -79,7 +79,7 @@ RSpec.describe Channel::TwilioSms do
|
||||
let(:channel) { create(:channel_twilio_sms, :with_phone_number) }
|
||||
|
||||
it 'sends via twilio client' do
|
||||
expect(twilio_messages).to receive(:create).with(
|
||||
expect(twilio_messages).to receive(:create!).with(
|
||||
from: channel.phone_number,
|
||||
to: '+15555550111',
|
||||
body: 'hello world',
|
||||
@ -92,7 +92,7 @@ RSpec.describe Channel::TwilioSms do
|
||||
|
||||
context 'with media urls' do
|
||||
it 'supplies a media url' do
|
||||
expect(twilio_messages).to receive(:create).with(
|
||||
expect(twilio_messages).to receive(:create!).with(
|
||||
messaging_service_sid: channel.messaging_service_sid,
|
||||
to: '+15555550111',
|
||||
body: 'hello world',
|
||||
|
||||
@ -34,7 +34,7 @@ shared_examples_for 'assignment_handler' do
|
||||
it 'changes assignee to nil if they doesnt belong to the team and allow_auto_assign is false' do
|
||||
expect(team.allow_auto_assign).to be false
|
||||
|
||||
conversation.update(team: team)
|
||||
conversation.update!(team: team)
|
||||
|
||||
expect(conversation.reload.assignee).to be_nil
|
||||
end
|
||||
@ -42,7 +42,7 @@ shared_examples_for 'assignment_handler' do
|
||||
it 'changes assignee to a team member if allow_auto_assign is enabled' do
|
||||
team.update!(allow_auto_assign: true)
|
||||
|
||||
conversation.update(team: team)
|
||||
conversation.update!(team: team)
|
||||
|
||||
expect(conversation.reload.assignee).to eq agent
|
||||
expect(Conversations::ActivityMessageJob).to(have_been_enqueued.at_least(:once)
|
||||
@ -55,9 +55,9 @@ shared_examples_for 'assignment_handler' do
|
||||
assignee = create(:user, account: conversation.account, role: :agent)
|
||||
create(:inbox_member, user: assignee, inbox: conversation.inbox)
|
||||
create(:team_member, team: team, user: assignee)
|
||||
conversation.update(assignee: assignee)
|
||||
conversation.update!(assignee: assignee)
|
||||
|
||||
conversation.update(team: team)
|
||||
conversation.update!(team: team)
|
||||
|
||||
expect(conversation.reload.assignee).to eq assignee
|
||||
end
|
||||
|
||||
@ -27,7 +27,7 @@ shared_examples_for 'auto_assignment_handler' do
|
||||
end
|
||||
|
||||
it 'will not auto assign agent if enable_auto_assignment is false' do
|
||||
inbox.update(enable_auto_assignment: false)
|
||||
inbox.update!(enable_auto_assignment: false)
|
||||
|
||||
expect(conversation.reload.assignee).to be_nil
|
||||
end
|
||||
|
||||
@ -14,7 +14,7 @@ RSpec.describe ContactInbox do
|
||||
it 'does not get updated on object update' do
|
||||
obj = contact_inbox
|
||||
old_token = obj.pubsub_token
|
||||
obj.update(source_id: '234234323')
|
||||
obj.update!(source_id: '234234323')
|
||||
expect(obj.pubsub_token).to eq(old_token)
|
||||
end
|
||||
|
||||
@ -32,7 +32,7 @@ RSpec.describe ContactInbox do
|
||||
expect(results.first['pubsub_token']).to be_nil
|
||||
|
||||
new_token = obj.pubsub_token
|
||||
obj.update(source_id: '234234323')
|
||||
obj.update!(source_id: '234234323')
|
||||
# the generated token shoul be persisted in db
|
||||
expect(obj.pubsub_token).to eq(new_token)
|
||||
end
|
||||
|
||||
@ -126,7 +126,7 @@ RSpec.describe Conversation do
|
||||
end
|
||||
|
||||
it 'sends conversation updated event if labels are updated' do
|
||||
conversation.update(label_list: [label.title])
|
||||
conversation.update!(label_list: [label.title])
|
||||
changed_attributes = conversation.previous_changes
|
||||
expect(Rails.configuration.dispatcher).to have_received(:dispatch)
|
||||
.with(
|
||||
@ -140,7 +140,7 @@ RSpec.describe Conversation do
|
||||
end
|
||||
|
||||
it 'runs after_update callbacks' do
|
||||
conversation.update(
|
||||
conversation.update!(
|
||||
status: :resolved,
|
||||
contact_last_seen_at: Time.zone.now,
|
||||
assignee: new_assignee
|
||||
@ -169,7 +169,7 @@ RSpec.describe Conversation do
|
||||
end
|
||||
|
||||
it 'will not run conversation_updated event for non whitelisted keys' do
|
||||
conversation.update(updated_at: DateTime.now.utc)
|
||||
conversation.update!(updated_at: DateTime.now.utc)
|
||||
expect(Rails.configuration.dispatcher).not_to have_received(:dispatch)
|
||||
.with(described_class::CONVERSATION_UPDATED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true)
|
||||
end
|
||||
@ -191,7 +191,7 @@ RSpec.describe Conversation do
|
||||
end
|
||||
|
||||
it 'creates conversation activities' do
|
||||
conversation.update(
|
||||
conversation.update!(
|
||||
status: :resolved,
|
||||
contact_last_seen_at: Time.zone.now,
|
||||
assignee: new_assignee,
|
||||
@ -213,7 +213,7 @@ RSpec.describe Conversation do
|
||||
end
|
||||
|
||||
it 'adds a message for system auto resolution if marked resolved by system' do
|
||||
account.update(auto_resolve_duration: 40)
|
||||
account.update!(auto_resolve_duration: 40)
|
||||
conversation2 = create(:conversation, status: 'open', account: account, assignee: old_assignee)
|
||||
Current.user = nil
|
||||
|
||||
@ -615,9 +615,9 @@ RSpec.describe Conversation do
|
||||
|
||||
context 'when instagram channel' do
|
||||
it 'return true with HUMAN_AGENT if it is outside of 24 hour window' do
|
||||
InstallationConfig.where(name: 'ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT').first_or_create(value: true)
|
||||
InstallationConfig.where(name: 'ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT').first_or_create!(value: true)
|
||||
|
||||
conversation.update(additional_attributes: { type: 'instagram_direct_message' })
|
||||
conversation.update!(additional_attributes: { type: 'instagram_direct_message' })
|
||||
create(
|
||||
:message,
|
||||
account: conversation.account,
|
||||
@ -630,9 +630,9 @@ RSpec.describe Conversation do
|
||||
end
|
||||
|
||||
it 'return false without HUMAN_AGENT if it is outside of 24 hour window' do
|
||||
InstallationConfig.where(name: 'ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT').first_or_create(value: false)
|
||||
InstallationConfig.where(name: 'ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT').first_or_create!(value: false)
|
||||
|
||||
conversation.update(additional_attributes: { type: 'instagram_direct_message' })
|
||||
conversation.update!(additional_attributes: { type: 'instagram_direct_message' })
|
||||
create(
|
||||
:message,
|
||||
account: conversation.account,
|
||||
@ -878,7 +878,7 @@ RSpec.describe Conversation do
|
||||
let(:conversation) { create(:conversation) }
|
||||
|
||||
it 'returns the correct list of labels' do
|
||||
conversation.update(label_list: %w[customer-support enterprise paid-customer])
|
||||
conversation.update!(label_list: %w[customer-support enterprise paid-customer])
|
||||
|
||||
expect(conversation.cached_label_list_array).to eq %w[customer-support enterprise paid-customer]
|
||||
end
|
||||
|
||||
@ -226,7 +226,7 @@ RSpec.describe Inbox do
|
||||
|
||||
it 'set portal id in inbox' do
|
||||
inbox.portal_id = portal.id
|
||||
inbox.save
|
||||
inbox.save!
|
||||
|
||||
expect(inbox.portal).to eq(portal)
|
||||
end
|
||||
@ -234,7 +234,7 @@ RSpec.describe Inbox do
|
||||
it 'sends the inbox_created event if ENABLE_INBOX_EVENTS is true' do
|
||||
with_modified_env ENABLE_INBOX_EVENTS: 'true' do
|
||||
channel = inbox.channel
|
||||
channel.update(widget_color: '#fff')
|
||||
channel.update!(widget_color: '#fff')
|
||||
|
||||
expect(Rails.configuration.dispatcher).to have_received(:dispatch)
|
||||
.with(
|
||||
@ -248,7 +248,7 @@ RSpec.describe Inbox do
|
||||
|
||||
it 'sends the inbox_created event if ENABLE_INBOX_EVENTS is false' do
|
||||
channel = inbox.channel
|
||||
channel.update(widget_color: '#fff')
|
||||
channel.update!(widget_color: '#fff')
|
||||
|
||||
expect(Rails.configuration.dispatcher).not_to have_received(:dispatch)
|
||||
.with(
|
||||
@ -261,7 +261,7 @@ RSpec.describe Inbox do
|
||||
|
||||
it 'resets cache key if there is an update in the channel' do
|
||||
channel = inbox.channel
|
||||
channel.update(widget_color: '#fff')
|
||||
channel.update!(widget_color: '#fff')
|
||||
|
||||
expect(Rails.configuration.dispatcher).to have_received(:dispatch)
|
||||
.with(
|
||||
@ -274,7 +274,7 @@ RSpec.describe Inbox do
|
||||
|
||||
it 'updates the cache key after update' do
|
||||
expect(inbox.account).to receive(:update_cache_key).with('inbox')
|
||||
inbox.update(name: 'New Name')
|
||||
inbox.update!(name: 'New Name')
|
||||
end
|
||||
|
||||
it 'updates the cache key after touch' do
|
||||
|
||||
@ -46,13 +46,13 @@ RSpec.describe Label do
|
||||
it 'calls update job' do
|
||||
expect(Labels::UpdateJob).to receive(:perform_later).with('new-title', label.title, label.account_id)
|
||||
|
||||
label.update(title: 'new-title')
|
||||
label.update!(title: 'new-title')
|
||||
end
|
||||
|
||||
it 'does not call update job if title is not updated' do
|
||||
expect(Labels::UpdateJob).not_to receive(:perform_later)
|
||||
|
||||
label.update(description: 'new-description')
|
||||
label.update!(description: 'new-description')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -237,7 +237,7 @@ RSpec.describe Message do
|
||||
end
|
||||
|
||||
it 'sets the waiting_since if there is an incoming message' do
|
||||
conversation.update(waiting_since: nil)
|
||||
conversation.update!(waiting_since: nil)
|
||||
message.message_type = :incoming
|
||||
message.save!
|
||||
|
||||
|
||||
@ -27,13 +27,13 @@ RSpec.describe Portal do
|
||||
end
|
||||
|
||||
it 'Does not allow any other config than allowed_locales' do
|
||||
portal.update(config: { 'some_other_key': 'test_value' })
|
||||
expect(portal.update(config: { 'some_other_key': 'test_value' })).to be(false)
|
||||
expect(portal).not_to be_valid
|
||||
expect(portal.errors.full_messages[0]).to eq('Cofig in portal on some_other_key is not supported.')
|
||||
expect(portal.errors.full_messages[0]).to eq('Config in portal on some_other_key is not supported.')
|
||||
end
|
||||
|
||||
it 'converts empty string to nil' do
|
||||
portal.update(custom_domain: '')
|
||||
portal.update!(custom_domain: '')
|
||||
expect(portal.custom_domain).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -56,7 +56,7 @@ RSpec.describe WorkingHour do
|
||||
|
||||
before do
|
||||
Time.zone = 'UTC'
|
||||
inbox.working_hours.find_by(day_of_week: 5).update(open_all_day: true)
|
||||
inbox.working_hours.find_by(day_of_week: 5).update!(open_all_day: true)
|
||||
travel_to '18.02.2022 11:00'.to_datetime
|
||||
end
|
||||
|
||||
@ -74,7 +74,7 @@ RSpec.describe WorkingHour do
|
||||
|
||||
before do
|
||||
Time.zone = 'UTC'
|
||||
inbox.working_hours.find_by(day_of_week: 5).update(open_all_day: true)
|
||||
inbox.working_hours.find_by(day_of_week: 5).update!(open_all_day: true)
|
||||
travel_to '18.02.2022 11:00'.to_datetime
|
||||
end
|
||||
|
||||
@ -94,7 +94,7 @@ RSpec.describe WorkingHour do
|
||||
|
||||
before do
|
||||
Time.zone = 'Australia/Sydney'
|
||||
inbox.update(timezone: 'Australia/Sydney')
|
||||
inbox.update!(timezone: 'Australia/Sydney')
|
||||
travel_to '10.10.2022 9:00 AEDT'
|
||||
end
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ RSpec.describe 'Api::V1::Accounts::Integrations::Slacks' do
|
||||
context 'when it is an authenticated user' do
|
||||
it 'updates hook if the channel id is correct' do
|
||||
channel_builder = double
|
||||
expect(channel_builder).to receive(:update).and_return(hook)
|
||||
expect(channel_builder).to receive(:update_reference_id).and_return(hook)
|
||||
expect(Integrations::Slack::ChannelBuilder).to receive(:new).and_return(channel_builder)
|
||||
|
||||
put "/api/v1/accounts/#{account.id}/integrations/slack",
|
||||
@ -55,7 +55,7 @@ RSpec.describe 'Api::V1::Accounts::Integrations::Slacks' do
|
||||
|
||||
it 'does not update the hook if the channel id is not correct' do
|
||||
channel_builder = double
|
||||
expect(channel_builder).to receive(:update)
|
||||
expect(channel_builder).to receive(:update_reference_id)
|
||||
expect(Integrations::Slack::ChannelBuilder).to receive(:new).and_return(channel_builder)
|
||||
|
||||
put "/api/v1/accounts/#{account.id}/integrations/slack",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user