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