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:
Gabriel Jablonski 2025-04-03 23:10:23 -03:00 committed by gabrieljablonski
parent e0708ca6f8
commit 659c3e7c2f
114 changed files with 301 additions and 298 deletions

View File

@ -170,3 +170,10 @@ AllCops:
Layout/LeadingCommentSpace: Layout/LeadingCommentSpace:
Enabled: false Enabled: false
Rails/SaveBang:
Enabled: true
AllowedReceivers:
- Stripe::Subscription
- Stripe::Customer
- FactoryBot

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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!

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = [])

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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',

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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',

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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',

View File

@ -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,

View File

@ -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')

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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)

View File

@ -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] } })

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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',

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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!

View File

@ -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

View File

@ -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