-
Notifications
You must be signed in to change notification settings - Fork 896
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16799 from gmcculloug/service_dialog_retirement
Service retirement values from dialog
- Loading branch information
Showing
7 changed files
with
331 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
145 changes: 145 additions & 0 deletions
145
spec/models/service/dialog_properties/retirement_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.