From 9cfeec86bec2f2c567b632574409bbc4a5649398 Mon Sep 17 00:00:00 2001 From: Ryan Lue Date: Mon, 23 Jul 2018 16:28:21 +0800 Subject: [PATCH] Update CallerId table when user phone numbers change (partially fixes #2057) --- app/models/user.rb | 13 ++++++++++ spec/models/user_spec.rb | 53 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index 86d17cd5e..4139703e9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -24,6 +24,7 @@ class User < ApplicationModel before_update :check_preferences_default, :validate_preferences, :validate_ooo, :reset_login_failed, :validate_agent_limit_by_attributes, :last_admin_check_by_attribute after_create :avatar_for_email_check after_update :avatar_for_email_check + after_commit :update_caller_id before_destroy :destroy_longer_required_objects store :preferences @@ -1191,4 +1192,16 @@ raise 'Minimum one user need to have admin permissions' self.login_failed = 0 true end + + # When adding/removing a phone number from the User table, + # update caller ID table + # to adopt/orphan matching Cti::Logs accordingly + # (see https://github.com/zammad/zammad/issues/2057) + def update_caller_id + # skip if "phone" does not change, or changes like [nil, ""] + return if persisted? && !previous_changes[:phone]&.any?(&:present?) + return if destroyed? && phone.blank? + + Cti::CallerId.build(self) + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 857dd9dd0..f17817753 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -5,6 +5,7 @@ require 'models/concerns/has_groups_permissions_examples' require 'models/concerns/can_lookup_examples' RSpec.describe User do + let(:subject) { create(:user, user_attrs || {}) } let(:group_access_instance) { create(:agent_user) } let(:new_group_access_instance) { build(:agent_user) } let(:group_access_no_permission_instance) { build(:user) } @@ -665,4 +666,56 @@ RSpec.describe User do end end end + + context 'when phone attribute' do + let(:user_attrs) { { phone: orig_number } } + + context 'included on create' do + let(:orig_number) { '1234567890' } + + it 'adds corresponding CallerId record' do + expect { subject } + .to change { Cti::CallerId.where(caller_id: orig_number).count }.by(1) + end + end + + context 'added on update' do + let(:orig_number) { nil } + let(:new_number) { '1234567890' } + + before { subject } # create user + + it 'adds corresponding CallerId record' do + expect { subject.update(phone: new_number) } + .to change { Cti::CallerId.where(caller_id: new_number).count }.by(1) + end + end + + context 'removed on update' do + let(:orig_number) { '1234567890' } + let(:new_number) { nil } + + before { subject } # create user + + it 'removes corresponding CallerId record' do + expect { subject.update(phone: nil) } + .to change { Cti::CallerId.where(caller_id: orig_number).count }.by(-1) + end + end + + context 'changed on update' do + let(:orig_number) { '1234567890' } + let(:new_number) { orig_number.next } + + before { subject } # create user + + it 'replaces CallerId record' do + # rubocop:disable Layout/MultilineMethodCallIndentation + expect { subject.update(phone: new_number) } + .to change { Cti::CallerId.where(caller_id: orig_number).count }.by(-1) + .and change { Cti::CallerId.where(caller_id: new_number).count }.by(1) + # rubocop:enable Layout/MultilineMethodCallIndentation + end + end + end end