Skip to content

Commit

Permalink
Merge pull request #16799 from gmcculloug/service_dialog_retirement
Browse files Browse the repository at this point in the history
Service retirement values from dialog
(cherry picked from commit def0da5)

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1626475
  • Loading branch information
mkanoor authored and simaishi committed Sep 7, 2018
1 parent d2e1645 commit ebe8ceb
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 41 deletions.
20 changes: 3 additions & 17 deletions app/models/service.rb
Expand Up @@ -48,7 +48,7 @@ class Service < ApplicationRecord
virtual_has_one :chargeback_report

before_validation :set_tenant_from_group
before_create :apply_dialog_settings
before_create :update_attributes_from_dialog

delegate :custom_actions, :custom_action_buttons, :to => :service_template, :allow_nil => true
delegate :provision_dialog, :to => :miq_request, :allow_nil => true
Expand Down Expand Up @@ -399,21 +399,7 @@ def remove_from_service(parenent_service)
parenent_service.remove_resource(self)
end

private

def apply_dialog_settings
dialog_options = options[:dialog] || {}

%w(dialog_service_name dialog_service_description).each do |field_name|
send(field_name, dialog_options[field_name]) if dialog_options.key?(field_name)
end
end

def dialog_service_name(value)
self.name = value if value.present?
end

def dialog_service_description(value)
self.description = value if value.present?
private def update_attributes_from_dialog
Service::DialogProperties.parse(options[:dialog], evm_owner).each { |key, value| self[key] = value }
end
end
21 changes: 21 additions & 0 deletions app/models/service/dialog_properties.rb
@@ -0,0 +1,21 @@
class Service
class DialogProperties
require_nested :Retirement

def initialize(options, user)
@options = options || {}
@user = user
end

def self.parse(options, user)
new(options, user).parse
end

def parse
Service::DialogProperties::Retirement.parse(@options, @user).tap do |attributes|
attributes[:name] = @options['dialog_service_name'] if @options['dialog_service_name'].present?
attributes[:description] = @options['dialog_service_description'] if @options['dialog_service_description'].present?
end
end
end
end
101 changes: 101 additions & 0 deletions app/models/service/dialog_properties/retirement.rb
@@ -0,0 +1,101 @@
class Service
class DialogProperties
class Retirement
RETIREMENT_WARN_FIELD_NAMES = %w(warn_on warn_in_days warn_in_hours warn_offset_days warn_offset_hours).freeze

def initialize(options, user)
@attributes = {}
@options = options || {}
@user = user
end

def self.parse(options, user)
new(options, user).parse
end

def parse
@attributes.tap { parse_options }
end

private

def parse_options
if @options['dialog_service_retires_on'].present?
field_name = 'dialog_service_retires_on'
self.retire_on_date = time_parse(@options[field_name])
elsif @options['dialog_service_retires_in_hours'].present?
field_name = 'dialog_service_retires_in_hours'
retires_in_duration(@options[field_name], :hours)
elsif @options['dialog_service_retires_in_days'].present?
field_name = 'dialog_service_retires_in_days'
retires_in_duration(@options[field_name], :days)
end
rescue StandardError
$log.error("Error parsing dialog retirement property [#{field_name}] with value [#{@options[field_name].inspect}]. Error: #{$!}")
end

def retires_in_duration(value, modifier)
self.retire_on_date = time_now + offset_set(value, modifier)
end

def offset_set(value, modifier)
value.to_i.send(modifier).tap do |offset|
raise "Offset cannot be a zero or negative value" if offset.zero? || offset.negative?
end
end

def retire_on_date=(value)
@attributes[:retires_on] = value
retirement_warning
end

def retirement_warning
warn_value = parse_retirement_warn
@attributes[:retirement_warn] = warn_value if warn_value
end

def parse_retirement_warn
warn_key, value = retirement_warn_properties

case warn_key
when 'warn_on'
time_parse(value)
when 'warn_in_days'
time_now + offset_set(value, :days)
when 'warn_in_hours'
time_now + offset_set(value, :hours)
when 'warn_offset_days'
@attributes[:retires_on] - offset_set(value, :days)
when 'warn_offset_hours'
@attributes[:retires_on] - offset_set(value, :hours)
end
end

def retirement_warn_properties
warn_name = RETIREMENT_WARN_FIELD_NAMES.detect do |field_name|
@options["dialog_service_retirement_#{field_name}"].present?
end

return warn_name, @options["dialog_service_retirement_#{warn_name}"] if warn_name
end

def time_parse(value)
with_user_timezone do
Time.zone.parse(value).utc.tap do |time|
raise "Retirement date cannot be set in the past" if time < time_now
end
end
end

def time_now
with_user_timezone { Time.zone.now.utc }
end

def with_user_timezone
user = @user || User.current_user

user ? user.with_my_timezone { yield } : yield
end
end
end
end
29 changes: 12 additions & 17 deletions app/models/service_template.rb
Expand Up @@ -171,23 +171,21 @@ def create_service(service_task, parent_svc = nil)
# Determine service name
# target_name = self.get_option(:target_name)
# nh['name'] = target_name unless target_name.blank?
svc = Service.create(nh)
svc.service_template = self
Service.create(nh) do |svc|
svc.service_template = self
set_ownership(svc, service_task.get_user)

# self.options[:service_guid] = svc.guid
service_resources.each do |sr|
nh = sr.attributes.dup
%w(id created_at updated_at service_template_id).each { |key| nh.delete(key) }
svc.add_resource(sr.resource, nh) unless sr.resource.nil?
end
service_resources.each do |sr|
nh = sr.attributes.dup
%w(id created_at updated_at service_template_id).each { |key| nh.delete(key) }
svc.add_resource(sr.resource, nh) unless sr.resource.nil?
end

if parent_svc
service_resource = ServiceResource.find_by(:id => service_task.options[:service_resource_id])
parent_svc.add_resource!(svc, service_resource)
if parent_svc
service_resource = ServiceResource.find_by(:id => service_task.options[:service_resource_id])
parent_svc.add_resource!(svc, service_resource)
end
end

svc.save
svc
end

def set_service_type
Expand Down Expand Up @@ -234,8 +232,6 @@ def create_tasks_for_service(service_task, parent_svc)
end
svc = create_service(service_task, parent_svc)

set_ownership(svc, service_task.get_user)

service_task.destination = svc

create_subtasks(service_task, svc)
Expand Down Expand Up @@ -288,7 +284,6 @@ def set_ownership(service, user)
else
$log.info "Setting Service Owning User to Name=#{user.name}, ID=#{user.id}"
end
service.save
end

def self.default_provisioning_entry_point(service_type)
Expand Down
145 changes: 145 additions & 0 deletions spec/models/service/dialog_properties/retirement_spec.rb
@@ -0,0 +1,145 @@
describe Service::DialogProperties::Retirement do
let(:time) { Time.new(2018, 7, 21, 12, 20, 0, 0) }

it 'with a nil parameter' do
options = nil
expect(described_class.parse(options, nil)).to eq({})
end

it 'with an empty hash' do
options = {}
expect(described_class.parse(options, nil)).to eq({})
end

context 'when setting retirement date' do
describe 'retires_on' do
it 'with invalid time' do
options = {'dialog_service_retires_on' => 'xyz'}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end

it 'with valid time' do
Timecop.freeze(time) do
options = {'dialog_service_retires_on' => time.to_s}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time)
expect(parsed_results[:retirement_warn]).to be_nil
end
end

it 'with an invalid date that has already past' do
Timecop.freeze(time) do
options = {'dialog_service_retires_on' => "2000-01-01"}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end
end
end

describe 'retires_in_hours' do
it 'with invalid time' do
options = {'dialog_service_retires_in_hours' => 'xyz'}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end

it 'with valid time' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_hours' => 5}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.hours)
expect(parsed_results[:retirement_warn]).to be_nil
end
end
end

describe 'retires_in_days' do
it 'with invalid time' do
options = {'dialog_service_retires_in_days' => 'xyz'}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end

it 'with valid time' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to be_nil
end
end
end
end

context 'when setting retirement warn date' do
it 'with retirement_warn_on' do
user = FactoryGirl.create(:user)
expect(user).to receive(:with_my_timezone).exactly(3).times.and_yield

Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5,
'dialog_service_retirement_warn_on' => (time + 1.day).to_s}
parsed_results = described_class.parse(options, user)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to eq(time + 1.day)
end
end

it 'with retirement_warn_in_days' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5,
'dialog_service_retirement_warn_in_days' => 1}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to eq(time + 1.day)
end
end

it 'with retirement_warn_offset_days' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5,
'dialog_service_retirement_warn_offset_days' => 4}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to eq(time + 1.day)
end
end

it 'with retirement_warn_in_hours' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_hours' => 5,
'dialog_service_retirement_warn_in_hours' => 1}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.hours)
expect(parsed_results[:retirement_warn]).to eq(time + 1.hour)
end
end

it 'with retirement_warn_offset_hours' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_hours' => 5,
'dialog_service_retirement_warn_offset_hours' => 4}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.hours)
expect(parsed_results[:retirement_warn]).to eq(time + 1.hour)
end
end
end
end
40 changes: 40 additions & 0 deletions spec/models/service/dialog_properties_spec.rb
@@ -0,0 +1,40 @@
describe Service::DialogProperties do
it 'with a nil parameter and nil user' do
options = nil
expect(described_class.parse(options, nil)).to eq({})
end

it 'with an empty hash parameter and nil user' do
options = {}
expect(described_class.parse(options, nil)).to eq({})
end

it `will call the Retirement class` do
expect(Service::DialogProperties::Retirement).to receive(:parse).with({}, nil).and_return({})
described_class.parse(nil, nil)
end

describe 'name' do
it 'with an empty name' do
options = {'dialog_service_name' => ' '}
expect(described_class.parse(options, nil)).to eq({})
end

it 'with option name' do
options = {'dialog_service_name' => 'name from dialog'}
expect(described_class.parse(options, nil)).to eq(:name => 'name from dialog')
end
end

describe 'description' do
it 'with an empty description' do
options = {'dialog_service_description' => ' '}
expect(described_class.parse(options, nil)).to eq({})
end

it 'with option description' do
options = {'dialog_service_description' => 'test description from dialog'}
expect(described_class.parse(options, nil)).to eq(:description => 'test description from dialog')
end
end
end

0 comments on commit ebe8ceb

Please sign in to comment.