Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1677, add the "Any tag" for batch update form #1692

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/assets/javascripts/build_tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ $(document).on('mass_update_modal_dialog:after_open', function (event, form) {
'name': 'routing_tag_ids[]',
'class': 'chosen',
'id': 'batch_update_routing_tag_ids',
'value': '', // reset default value
'value': null, // reset default value
'multiple': true
});
var tagsCheckbox = $('#mass_update_dialog_routing_tag_ids');
Expand Down
56 changes: 46 additions & 10 deletions app/forms/batch_update_form/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,53 @@ def form_data_boolean(_options)
# :display_name [Symbol] default :name.
# :primary_key [Symbol] default :id.
# :scope [Proc,Symbol,nil] optional.
# :input_html [Hash] Input options
# @return [Array<Array(2)>]
def form_data_foreign_key(options)
klass = options.fetch(:class_name).constantize
display_name = options.fetch(:display_name, :name)
primary_key = options.fetch(:primary_key, :id)
custom_scope = options[:scope]

scope = klass.all
scope = scope.public_send(custom_scope) if custom_scope.is_a?(Symbol)
scope = custom_scope.call(scope) if custom_scope.is_a?(Proc)
scope.pluck(display_name, primary_key)
def form_data_foreign_key(options = {})
opts = extract_foreign_key_options(options)
klass = opts[:class_name].constantize

relation = klass.all
relation = apply_foreign_key_sorting(relation, opts)
result = apply_select_attributes(relation, opts)
add_foreign_key_additional_options(result, opts)
end

def extract_foreign_key_options(options)
options.assert_valid_keys(:class_name, :display_name, :primary_key, :scope, :input_html, :type)
options[:input_html].assert_valid_keys(:additional_options) if options[:input_html].present?

{
class_name: options.fetch(:class_name),
display_name: options.fetch(:display_name, :name),
primary_key: options.fetch(:primary_key, :id),
scope: options[:scope],
additional_options: options.dig(:input_html, :additional_options) || []
}
end

def apply_foreign_key_sorting(relation, options)
if options[:scope].is_a?(Symbol)
relation = relation.public_send(options[:scope])
elsif options[:scope].respond_to?(:call)
relation = options[:scope].call(relation)
else
relation
end
end

def apply_select_attributes(relation, options)
relation.pluck(options[:display_name], options[:primary_key])
end

# Adds additional items for array collection.
#
# @param result [Array] The array of options to be modified.
# @param _options [Hash] The original options hash (unused).
#
# @return [Array] The modified array of options.
def add_foreign_key_additional_options(result, _options)
result
end

def form_data_integer_collection(options)
Expand Down
7 changes: 6 additions & 1 deletion app/forms/batch_update_form/destination.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class BatchUpdateForm::Destination < BatchUpdateForm::Base
include BatchUpdateForm::RoutingTagOptions

model_class 'Routing::Destination'
attribute :enabled, type: :boolean
attribute :prefix
Expand All @@ -25,7 +27,10 @@ class BatchUpdateForm::Destination < BatchUpdateForm::Base
attribute :asr_limit
attribute :acd_limit
attribute :short_calls_limit
attribute :routing_tag_ids, type: :foreign_key, class_name: 'Routing::RoutingTag'
attribute :routing_tag_ids, type: :foreign_key,
class_name: 'Routing::RoutingTag',
input_html: { additional_options: [{ label: Routing::RoutingTag::ANY_TAG, value: nil }] },
scope: ->(scope) { scope.order(:name) }

# presence validations
validates :dst_number_min_length, presence: true, if: :dst_number_min_length_changed?
Expand Down
7 changes: 6 additions & 1 deletion app/forms/batch_update_form/dialpeer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class BatchUpdateForm::Dialpeer < BatchUpdateForm::Base
include BatchUpdateForm::RoutingTagOptions

model_class 'Dialpeer'
attribute :enabled, type: :boolean
attribute :prefix
Expand Down Expand Up @@ -34,7 +36,10 @@ class BatchUpdateForm::Dialpeer < BatchUpdateForm::Base
attribute :src_rewrite_result
attribute :dst_rewrite_rule
attribute :dst_rewrite_result
attribute :routing_tag_ids, type: :foreign_key, class_name: 'Routing::RoutingTag'
attribute :routing_tag_ids, type: :foreign_key,
class_name: 'Routing::RoutingTag',
input_html: { additional_options: [{ label: Routing::RoutingTag::ANY_TAG, value: nil }] },
scope: ->(scope) { scope.order(:name) }

# presence
validates :dst_number_min_length, presence: true, if: :dst_number_min_length_changed?
Expand Down
20 changes: 20 additions & 0 deletions app/forms/batch_update_form/routing_tag_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module BatchUpdateForm::RoutingTagOptions
extend ActiveSupport::Concern

class_methods do
def add_foreign_key_additional_options(result, options)
additional_options = options[:additional_options]
# Expect additional_options to be an array of hashes, for example:
# [{ label: 'Any tag', value: nil }]
additional_options.each do |opt|
# Prepend each additional option to the result array.
# Each item is represented as [label, value].
result.prepend([opt[:label], opt[:value]])
end

result
end
end
end
62 changes: 55 additions & 7 deletions spec/features/routing/destinations/batch_update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
let!(:profit_control_mode_id) { Routing::RateProfitControlMode::MODE_PER_CALL }
let!(:routing_tags) { create_list(:routing_tag, 5) }

before do
visit destinations_path
click_button 'Update batch'
expect(page).to have_selector('.ui-dialog')
end

subject do
fill_batch_form
click_button 'OK'
Expand Down Expand Up @@ -46,7 +40,7 @@
asr_limit: '0.9',
acd_limit: '1',
short_calls_limit: '4',
routing_tag_ids: routing_tags.map { |tag| tag.id.to_s }
routing_tag_ids: routing_tags.sort_by(&:name).map { |tag| tag.id.to_s }
}
end

Expand Down Expand Up @@ -178,6 +172,12 @@
end

context 'should check validates' do
before do
visit destinations_path
click_button 'Update batch'
expect(page).to have_selector('.ui-dialog')
end

context 'when change :dp_margin_percent' do
let(:assign_params) { { dp_margin_percent: '0' } }

Expand Down Expand Up @@ -207,4 +207,52 @@
end
end
end

context 'when user wants to change routing_tag_ids to "NOT TAGGED"' do
subject { click_button :OK }

let(:_destinations) { nil }
let(:assign_params) { {} }

before do
visit destinations_path
click_button 'Update batch'
page.scroll_to find_button('OK')
check :Routing_tag_ids
# toggle checkbox and then leave it empty to chnage value to empty array
end

it 'should create Job to update routing_tag_ids field of desctination to default value: []' do
expect do
subject
expect(page).to have_selector '.flash', text: success_message
end.to enqueue_job(AsyncBatchUpdateJob).with('Routing::Destination', be_present, { routing_tag_ids: '' }, be_present)

# ensure that destination model converts "" to [] because the system consider [] as Routing::RoutingTag::NOT_TAGGED
expect(Routing::Destination.new(routing_tag_ids: '')).to have_attributes(routing_tag_ids: [])
end
end

context 'when user wants to change routing_tag_ids to "ANY TAG"' do
let(:_destinations) { nil }
let(:assign_params) { {} }

before do
visit destinations_path
click_button 'Update batch'
page.scroll_to find_button('OK')
check :Routing_tag_ids
end

it 'should create a Job to update routing_tag_ids to any tag: [nil]' do
fill_in_chosen 'routing_tag_ids[]', with: Routing::RoutingTag::ANY_TAG, multiple: true
expect do
subject
expect(page).to have_selector '.flash', text: success_message
end.to enqueue_job(AsyncBatchUpdateJob).with('Routing::Destination', be_present, { routing_tag_ids: [''] }, be_present)

# ensure that destination model converts [""] to [nil] because the system consider [nil] as Routing::RoutingTag::ANY_TAG
expect(Routing::Destination.new(routing_tag_ids: [''])).to have_attributes(routing_tag_ids: [nil])
end
end
end
26 changes: 25 additions & 1 deletion spec/features/routing/dialpeers/batch_update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
src_rewrite_result: '12',
dst_rewrite_rule: '12',
dst_rewrite_result: '12',
routing_tag_ids: routing_tags.map { |tag| tag.id.to_s }
routing_tag_ids: routing_tags.sort_by(&:name).map { |tag| tag.id.to_s }
}
end
let(:fill_batch_form) do
Expand Down Expand Up @@ -266,4 +266,28 @@
end
end
end

context 'when user wants to change routing_tag_ids to "ANY TAG"' do
subject { click_button :OK }

let(:_dialpeers) { nil }
let(:routing_group) { nil }
let!(:routeset_discriminator) { nil }
let(:assign_params) { {} }

before do
check :Routing_tag_ids
fill_in_chosen 'routing_tag_ids[]', with: Routing::RoutingTag::ANY_TAG, multiple: true
end

it 'should create a Job to update routing_tag_ids to any tag: [nil]' do
expect do
subject
expect(page).to have_selector '.flash', text: success_message
end.to enqueue_job(AsyncBatchUpdateJob).with('Dialpeer', be_present, { routing_tag_ids: [''] }, be_present)

# ensure that dialpeer model converts "" to [] because the system considers [""] as Routing::RoutingTag::ANY_TAG
expect(Dialpeer.new(routing_tag_ids: [''])).to have_attributes(routing_tag_ids: [nil])
end
end
end
Loading