Skip to content
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
6 changes: 4 additions & 2 deletions app/controllers/api/v3/scenarios_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ def update

if final_params[:scenario].blank?
authorize!(:read, @scenario)
elsif final_params[:scenario][:set_preset_roles].present?
elsif final_params[:scenario][:set_preset_roles].present? ||
final_params[:scenario][:saved_scenario_users].present?
authorize!(:destroy, @scenario)
else
authorize!(:update, @scenario)
Expand Down Expand Up @@ -472,7 +473,8 @@ def scenario_params
:set_preset_roles,
:source,
{ user_values: {} },
{ metadata: {} }
{ metadata: {} },
{ saved_scenario_users: %i[user_id user_email role_id] }
])

attrs = attrs[:scenario] || {}
Expand Down
25 changes: 25 additions & 0 deletions app/models/scenario.rb
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,25 @@ def copy_preset_roles
copy_roles_from_parent
end

# Upserts ScenarioUser records from an explicit list of user params. Used
# when MyETM pushes a SavedScenario's roles onto the underlying session.
def sync_users_from_params(user_params)
user_params.each do |entry|
entry = entry.with_indifferent_access

if (existing = find_scenario_user_by(entry))
existing.role_id = entry[:role_id]
existing.save(validate: false)
else
scenario_users.create!(
user_id: entry[:user_id].presence,
user_email: entry[:user_email].presence,
role_id: entry[:role_id]
)
end
end
end

private

def copy_roles_from_parent
Expand All @@ -382,6 +401,12 @@ def copy_roles_from_parent
end
end

def find_scenario_user_by(entry)
return scenario_users.find_by(user_id: entry[:user_id]) if entry[:user_id]

scenario_users.find_by(user_email: entry[:user_email]) if entry[:user_email]
end

# Validation method for when a user sets their metadata.
def validate_metadata_size
errors.add(:metadata, 'can not exceed 64Kb') if metadata.to_s.bytesize > 64.kilobytes
Expand Down
9 changes: 5 additions & 4 deletions app/models/scenario_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ def apply(scenario_data, (coupling_state, user_values, balanced_values))

# Post-save
def post_save(scenario_data, persisted)
set_preset_roles = truthy?(scenario_data[:set_preset_roles])
_post_saved = yield post_save_operations(set_preset_roles)
set_preset_roles = truthy?(scenario_data[:set_preset_roles])
saved_scenario_users = scenario_data[:saved_scenario_users]
_post_saved = yield post_save_operations(set_preset_roles, saved_scenario_users)
Success(persisted)
end

Expand Down Expand Up @@ -148,8 +149,8 @@ def persist_scenario(attributes)
service(:PersistScenario).call(scenario, attributes, skip_validation)
end

def post_save_operations(set_preset_roles)
service(:PostSaveOperations).call(scenario, set_preset_roles, current_user)
def post_save_operations(set_preset_roles, saved_scenario_users)
service(:PostSaveOperations).call(scenario, set_preset_roles, saved_scenario_users, current_user)
end

# Helper to instantiate services
Expand Down
9 changes: 8 additions & 1 deletion app/models/scenario_updater/services/post_save_operations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ class PostSaveOperations

TRUTHY_VALUES = Set.new([true, 'true', '1']).freeze

def call(scenario, set_preset_roles, current_user)
def call(scenario, set_preset_roles, saved_scenario_users, current_user)
copy_preset_roles_if_requested(scenario, set_preset_roles)
sync_saved_scenario_users(scenario, saved_scenario_users)
update_version_tag(scenario, current_user)

Success(scenario)
Expand All @@ -22,6 +23,12 @@ def copy_preset_roles_if_requested(scenario, set_preset_roles)
scenario.copy_preset_roles if should_copy
end

def sync_saved_scenario_users(scenario, saved_scenario_users)
return if saved_scenario_users.blank?

scenario.sync_users_from_params(saved_scenario_users)
end

def update_version_tag(scenario, current_user)
scenario.scenario_version_tag&.update(user: current_user)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/scenario_updater/services/prepare_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def call(scenario, user_values, balanced_values, scenario_data)

def filter_scenario_data(scenario, scenario_data)
scenario_data
.except(:area_code, :end_year, :set_preset_roles, :user_values)
.except(:area_code, :end_year, :set_preset_roles, :saved_scenario_users, :user_values)
.merge(metadata: metadata_to_apply(scenario, scenario_data))
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

it 'copies preset roles if requested' do
expect(scenario).to receive(:copy_preset_roles).with(no_args)
service.call(scenario, true, 'user')
service.call(scenario, true, '', 'user')
end

it 'updates version tag' do
version_tag = double('VersionTag')
allow(scenario).to receive(:scenario_version_tag).and_return(version_tag)
expect(version_tag).to receive(:update).with(user: 'user')
service.call(scenario, false, 'user')
service.call(scenario, false, '', 'user')
end
end