-
Notifications
You must be signed in to change notification settings - Fork 897
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support setting retires_on and retirement_warn for services from dialogs
Pass user so time parsing occurs in proper timezone.
- Loading branch information
1 parent
d025d39
commit 8a41883
Showing
5 changed files
with
256 additions
and
14 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 |
---|---|---|
@@ -1,17 +1,22 @@ | ||
class Service | ||
class DialogProperties | ||
def initialize(options) | ||
require_nested :Retirement | ||
|
||
def initialize(options, user) | ||
@attributes = {} | ||
@options = options || {} | ||
@user = user | ||
end | ||
|
||
def self.parse(options) | ||
new(options).parse | ||
def self.parse(options, user) | ||
new(options, user).parse | ||
end | ||
|
||
def parse | ||
@attributes[:name] = @options['dialog_service_name'] if @options['dialog_service_name'].present? | ||
@attributes[:description] = @options['dialog_service_description'] if @options['dialog_service_description'].present? | ||
|
||
@attributes.merge!(Service::DialogProperties::Retirement.parse(@options, @user)) | ||
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,97 @@ | ||
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 { Time.zone.parse(value).utc } | ||
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 |
135 changes: 135 additions & 0 deletions
135
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,135 @@ | ||
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 | ||
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).and_yield.twice | ||
|
||
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 |
---|---|---|
@@ -1,35 +1,40 @@ | ||
describe Service::DialogProperties do | ||
it 'with a nil parameter' do | ||
it 'with a nil parameter and nil user' do | ||
options = nil | ||
expect(described_class.parse(options)).to eq({}) | ||
expect(described_class.parse(options, nil)).to eq({}) | ||
end | ||
|
||
it 'with an empty hash' do | ||
it 'with an empty hash parameter and nil user' do | ||
options = {} | ||
expect(described_class.parse(options)).to eq({}) | ||
expect(described_class.parse(options, nil)).to eq({}) | ||
end | ||
|
||
context 'name' do | ||
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)).to eq({}) | ||
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)).to eq(:name => 'name from dialog') | ||
expect(described_class.parse(options, nil)).to eq(:name => 'name from dialog') | ||
end | ||
end | ||
|
||
context 'description' do | ||
describe 'description' do | ||
it 'with an empty description' do | ||
options = {'dialog_service_description' => ' '} | ||
expect(described_class.parse(options)).to eq({}) | ||
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)).to eq(:description => 'test description from dialog') | ||
expect(described_class.parse(options, nil)).to eq(:description => 'test description from dialog') | ||
end | ||
end | ||
end |