0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-22 09:20:29 +01:00

Fix specs and tighten conditional handling

Dieser Commit ist enthalten in:
angusmcleod 2021-06-23 16:13:58 +10:00
Ursprung d3c6733e59
Commit e441588aa3
19 geänderte Dateien mit 167 neuen und 72 gelöschten Zeilen

Datei anzeigen

@ -8,7 +8,7 @@ class CustomWizard::StepsController < ::ApplicationController
update[:fields] = {} update[:fields] = {}
if params[:fields] if params[:fields]
field_ids = @step_template['fields'].map { |f| f['id'] } field_ids = @builder.wizard.field_ids
params[:fields].each do |k, v| params[:fields].each do |k, v|
update[:fields][k] = v if field_ids.include? k update[:fields][k] = v if field_ids.include? k
end end
@ -36,11 +36,15 @@ class CustomWizard::StepsController < ::ApplicationController
if current_step.final? if current_step.final?
builder.template.actions.each do |action_template| builder.template.actions.each do |action_template|
if action_template['run_after'] === 'wizard_completion' if action_template['run_after'] === 'wizard_completion'
CustomWizard::Action.new( action_result = CustomWizard::Action.new(
action: action_template, action: action_template,
wizard: @wizard, wizard: @wizard,
data: current_submission submission: current_submission
).perform ).perform
if action_result.success?
current_submission = action_result.submission
end
end end
end end
@ -54,6 +58,8 @@ class CustomWizard::StepsController < ::ApplicationController
result[:final] = true result[:final] = true
else else
current_submission.save
result[:final] = false result[:final] = false
result[:next_step_id] = current_step.next.id result[:next_step_id] = current_step.next.id
end end

Datei anzeigen

@ -64,7 +64,7 @@ class CustomWizard::WizardController < ::ApplicationController
if user && wizard.can_access? if user && wizard.can_access?
submission = wizard.current_submission submission = wizard.current_submission
if submission && submission.redirect_to if submission.present? && submission.redirect_to
result.merge!(redirect_to: submission.redirect_to) result.merge!(redirect_to: submission.redirect_to)
end end

Datei anzeigen

@ -30,6 +30,9 @@ class CustomWizard::Action
end end
save_log save_log
@result.submission = @submission
@result
end end
def mapper_data def mapper_data

Datei anzeigen

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::ActionResult class CustomWizard::ActionResult
attr_accessor :success, :handler, :output attr_accessor :success, :handler, :output, :submission
def initialize def initialize
@success = false @success = false

Datei anzeigen

@ -47,8 +47,8 @@ class CustomWizard::Builder
step.on_update do |updater| step.on_update do |updater|
@updater = updater @updater = updater
@submission = @wizard.current_submission || CustomWizard::Submission.new(@wizard) @submission = @wizard.current_submission
@submission.fields.merge(@updater.submission) @submission.fields.merge!(@updater.submission)
@updater.validate @updater.validate
next if @updater.errors.any? next if @updater.errors.any?
@ -63,7 +63,9 @@ class CustomWizard::Builder
@submission.route_to = nil @submission.route_to = nil
@submission.save @submission.save
@wizard.update!
@updater.result[:redirect_on_next] = route_to if route_to @updater.result[:redirect_on_next] = route_to if route_to
true true
else else
false false
@ -72,7 +74,7 @@ class CustomWizard::Builder
end end
end end
@wizard.update_step_order! @wizard.update!
@wizard @wizard
end end
@ -89,7 +91,7 @@ class CustomWizard::Builder
params[:value] = prefill_field(field_template, step_template) params[:value] = prefill_field(field_template, step_template)
if !build_opts[:reset] && (submission = @wizard.current_submission) if !build_opts[:reset] && (submission = @wizard.current_submission).present?
params[:value] = submission.fields[field_template['id']] if submission.fields[field_template['id']] params[:value] = submission.fields[field_template['id']] if submission.fields[field_template['id']]
end end
@ -272,14 +274,15 @@ class CustomWizard::Builder
permitted_data = {} permitted_data = {}
submission_key = nil submission_key = nil
params_key = nil params_key = nil
submission = @wizard.current_submission || CustomWizard::Submission.new(@wizard) submission = @wizard.current_submission
permitted_params.each do |pp| permitted_params.each do |pp|
pair = pp['pairs'].first pair = pp['pairs'].first
params_key = pair['key'].to_sym params_key = pair['key'].to_sym
submission_key = pair['value'].to_sym submission_key = pair['value'].to_sym
if submission_key && params_key if submission_key && params_key && params[params_key].present?
submission.permitted_param_keys << submission_key.to_s
submission.fields[submission_key] = params[params_key] submission.fields[submission_key] = params[params_key]
end end
end end
@ -293,7 +296,7 @@ class CustomWizard::Builder
pair['key'].present? && pair['value'].present? pair['key'].present? && pair['value'].present?
end end
if pairs.any? && !@wizard.current_submission if pairs.any? && !@wizard.current_submission.present?
step.permitted = false step.permitted = false
break break
end end
@ -323,11 +326,15 @@ class CustomWizard::Builder
if @template.actions.present? if @template.actions.present?
@template.actions.each do |action_template| @template.actions.each do |action_template|
if action_template['run_after'] === updater.step.id if action_template['run_after'] === updater.step.id
CustomWizard::Action.new( result = CustomWizard::Action.new(
action: action_template, action: action_template,
wizard: @wizard, wizard: @wizard,
submission: @submission submission: @submission
).perform ).perform
if result.success?
@submission = result.submission
end
end end
end end
end end

Datei anzeigen

@ -2,14 +2,15 @@ class CustomWizard::Submission
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
KEY ||= "submissions" KEY ||= "submissions"
ACTION_KEY ||= "action"
META ||= %w(submitted_at route_to redirect_on_complete redirect_to) META ||= %w(submitted_at route_to redirect_on_complete redirect_to)
attr_reader :id, attr_reader :id,
:user, :user,
:user_id,
:wizard :wizard
attr_accessor :fields attr_accessor :fields,
:permitted_param_keys
META.each do |attr| META.each do |attr|
class_eval { attr_accessor attr } class_eval { attr_accessor attr }
@ -17,9 +18,10 @@ class CustomWizard::Submission
def initialize(wizard, data = {}, user_id = nil) def initialize(wizard, data = {}, user_id = nil)
@wizard = wizard @wizard = wizard
@user_id = user_id
if user_id if user_id
@user = User.find_by(id: user_id) || OpenStruct.new(deleted: true, id: user_id) @user = User.find_by(id: user_id)
else else
@user = wizard.user @user = wizard.user
end end
@ -31,23 +33,30 @@ class CustomWizard::Submission
META.each do |attr| META.each do |attr|
send("#{attr}=", data[attr]) if data[attr] send("#{attr}=", data[attr]) if data[attr]
end end
@permitted_param_keys = data['permitted_param_keys'] || []
end end
def save def save
return nil unless wizard.save_submissions return nil unless wizard.save_submissions
validate_fields validate
submissions = self.class.list(wizard, user_id: user.id).select { |s| s.id != self.id } submission_list = self.class.list(wizard, user_id: user.id)
submissions = submission_list.select { |submission| submission.id != self.id }
submissions.push(self) submissions.push(self)
submission_data = submissions.map { |s| s.fields_and_meta } submission_data = submissions.map { |submission| data_to_save(submission) }
PluginStore.set("#{wizard.id}_#{KEY}", user.id, submission_data) PluginStore.set("#{wizard.id}_#{KEY}", user.id, submission_data)
end end
def validate_fields def validate
self.fields = fields.select do |key, value| self.fields = fields.select { |key, value| validate_field_key(key) }
wizard.field_ids.include?(key) || key.include?(ACTION_KEY)
end end
def validate_field_key(key)
wizard.field_ids.include?(key) ||
wizard.action_ids.include?(key) ||
permitted_param_keys.include?(key)
end end
def fields_and_meta def fields_and_meta
@ -62,6 +71,24 @@ class CustomWizard::Submission
result result
end end
def present?
fields_and_meta.present?
end
def data_to_save(submission)
data = {
id: submission.id
}
data.merge!(submission.fields_and_meta)
if submission.permitted_param_keys.present?
data[:permitted_param_keys] = submission.permitted_param_keys
end
data
end
def self.get(wizard, user_id) def self.get(wizard, user_id)
data = PluginStore.get("#{wizard.id}_#{KEY}", user_id).first data = PluginStore.get("#{wizard.id}_#{KEY}", user_id).first
new(wizard, data, user_id) new(wizard, data, user_id)

Datei anzeigen

@ -26,12 +26,16 @@ class CustomWizard::Wizard
:needs_groups, :needs_groups,
:steps, :steps,
:step_ids, :step_ids,
:field_ids,
:first_step, :first_step,
:start, :start,
:actions, :actions,
:action_ids,
:user, :user,
:submissions :submissions
attr_reader :all_step_ids
def initialize(attrs = {}, user = nil) def initialize(attrs = {}, user = nil)
@user = user @user = user
attrs = attrs.with_indifferent_access attrs = attrs.with_indifferent_access
@ -59,11 +63,22 @@ class CustomWizard::Wizard
@first_step = nil @first_step = nil
@steps = [] @steps = []
if attrs['steps'].present? if attrs['steps'].present?
@step_ids = attrs['steps'].map { |s| s['id'] } @step_ids = @all_step_ids = attrs['steps'].map { |s| s['id'] }
@field_ids = []
attrs['steps'].each do |step|
if step['fields'].present?
step['fields'].each do |field|
@field_ids << field['id']
end
end
end
end end
@actions = [] @actions = attrs['actions'] || []
@action_ids = @actions.map { |a| a['id'] }
end end
def cast_bool(val) def cast_bool(val)
@ -84,7 +99,19 @@ class CustomWizard::Wizard
step.index = (steps.size == 1 ? 0 : steps.size) if step.index.nil? step.index = (steps.size == 1 ? 0 : steps.size) if step.index.nil?
end end
def update_step_order! def update!
update_step_order
update_step_ids
update_field_ids
update_action_ids
@submissions = nil
@current_submission = nil
true
end
def update_step_order
steps.sort_by!(&:index) steps.sort_by!(&:index)
steps.each_with_index do |step, index| steps.each_with_index do |step, index|
@ -103,7 +130,7 @@ class CustomWizard::Wizard
step.conditional_final_step = true step.conditional_final_step = true
end end
if index === (step_ids.length - 1) if index === (all_step_ids.length - 1)
step.last_step = true step.last_step = true
end end
@ -118,7 +145,7 @@ class CustomWizard::Wizard
acting_user_id: user.id, acting_user_id: user.id,
action: ::UserHistory.actions[:custom_wizard_step], action: ::UserHistory.actions[:custom_wizard_step],
context: id, context: id,
subject: step_ids subject: all_step_ids
).order("created_at").last ).order("created_at").last
last_completed_step.subject last_completed_step.subject
@ -222,8 +249,25 @@ class CustomWizard::Wizard
@groups ||= ::Site.new(Guardian.new(user)).groups @groups ||= ::Site.new(Guardian.new(user)).groups
end end
def field_ids def update_step_ids
steps.map { |step| step.fields.map { |field| field.id } }.flatten @step_ids = steps.map(&:id)
end
def update_field_ids
@field_ids = steps.map { |step| step.fields.map { |field| field.id } }.flatten
end
def update_action_ids
@action_ids = []
@actions.each do |action|
if action['run_after'].blank? ||
action['run_after'] === 'wizard_completion' ||
step_ids.include?(action['run_after'])
@action_ids << action['id']
end
end
end end
def submissions def submissions
@ -235,9 +279,9 @@ class CustomWizard::Wizard
@current_submission ||= begin @current_submission ||= begin
if submissions.present? if submissions.present?
unsubmitted = submissions.select { |submission| !submission.submitted_at } unsubmitted = submissions.select { |submission| !submission.submitted_at }
unsubmitted.present? ? unsubmitted.first : nil unsubmitted.present? ? unsubmitted.first : CustomWizard::Submission.new(self)
else else
nil CustomWizard::Submission.new(self)
end end
end end
end end
@ -252,6 +296,8 @@ class CustomWizard::Wizard
current_submission.submitted_at = Time.now.iso8601 current_submission.submitted_at = Time.now.iso8601
current_submission.save current_submission.save
end end
update!
end end
def self.create(wizard_id, user = nil) def self.create(wizard_id, user = nil)
@ -321,7 +367,7 @@ class CustomWizard::Wizard
wizard = self.create(wizard_id, user) wizard = self.create(wizard_id, user)
if wizard.permitted? if wizard.permitted?
submission = wizard.current_submission || CustomWizard::Submission.new(wizard) submission = wizard.current_submission
submission.redirect_to = url submission.redirect_to = url
submission.save submission.save
else else

Datei anzeigen

@ -86,6 +86,7 @@ after_initialize do
../serializers/custom_wizard/wizard_step_serializer.rb ../serializers/custom_wizard/wizard_step_serializer.rb
../serializers/custom_wizard/wizard_serializer.rb ../serializers/custom_wizard/wizard_serializer.rb
../serializers/custom_wizard/log_serializer.rb ../serializers/custom_wizard/log_serializer.rb
../serializers/custom_wizard/submission_serializer.rb
../serializers/custom_wizard/realtime_validation/similar_topics_serializer.rb ../serializers/custom_wizard/realtime_validation/similar_topics_serializer.rb
../extensions/extra_locales_controller.rb ../extensions/extra_locales_controller.rb
../extensions/invites_controller.rb ../extensions/invites_controller.rb

Datei anzeigen

@ -1,13 +0,0 @@
class CustomWizard::SubmissionSerializer
attributes :id,
:username,
:fields,
:redirect_to,
:submitted_at
def username
object.user.deleted ?
I18n.t('admin.wizard.submission.no_user', user_id: object.user.id) :
object.user.username
end
end

Datei anzeigen

@ -0,0 +1,16 @@
# frozen_string_literal: true
class CustomWizard::SubmissionSerializer < ApplicationSerializer
attributes :id,
:username,
:fields,
:submitted_at,
:route_to,
:redirect_on_complete,
:redirect_to
def username
object.user.present? ?
object.user.username :
I18n.t('admin.wizard.submission.no_user', user_id: object.user_id)
end
end

Datei anzeigen

@ -194,11 +194,10 @@ describe CustomWizard::Action do
open_composer['post_template'] = "Body & more body & more body".dup open_composer['post_template'] = "Body & more body & more body".dup
wizard = CustomWizard::Wizard.new(@template, user) wizard = CustomWizard::Wizard.new(@template, user)
action = CustomWizard::Action.new( action = CustomWizard::Action.new(
wizard: wizard, wizard: wizard,
action: open_composer, action: open_composer,
data: {} submission: wizard.current_submission
) )
action.perform action.perform

Datei anzeigen

@ -257,10 +257,7 @@ describe CustomWizard::Builder do
it 'is permitted if required data is present' do it 'is permitted if required data is present' do
wizard = CustomWizard::Wizard.create('super_mega_fun_wizard', user) wizard = CustomWizard::Wizard.create('super_mega_fun_wizard', user)
data = { CustomWizard::Submission.new(wizard, step_1_field_1: "required").save
step_1_field_1: 'I am a user submission'
}
CustomWizard::Submission.new(wizard, data).save
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
@ -280,7 +277,7 @@ describe CustomWizard::Builder do
wizard = CustomWizard::Builder.new(@template[:id], user).build({}, wizard = CustomWizard::Builder.new(@template[:id], user).build({},
param: 'param_value' param: 'param_value'
) )
expect(wizard.current_submission['saved_param']).to eq('param_value') expect(wizard.current_submission.fields['saved_param']).to eq('param_value')
end end
end end
@ -362,7 +359,7 @@ describe CustomWizard::Builder do
it "does not save submissions" do it "does not save submissions" do
perform_update('step_1', step_1_field_1: 'Text input') perform_update('step_1', step_1_field_1: 'Text input')
expect(@wizard.current_submission).to eq(nil) expect(@wizard.current_submission.present?).to eq(false)
end end
end end
end end

Datei anzeigen

@ -29,7 +29,7 @@ describe CustomWizard::Submission do
it "saves a user's submission" do it "saves a user's submission" do
expect( expect(
described_class.get(template_json["id"], user.id).fields["step_1_field_1"] described_class.get(@wizard, user.id).fields["step_1_field_1"]
).to eq("I am a user submission") ).to eq("I am a user submission")
end end
@ -38,6 +38,6 @@ describe CustomWizard::Submission do
end end
it "list submissions by wizard and user" do it "list submissions by wizard and user" do
expect(described_class.list(@wizard, user).size).to eq(1) expect(described_class.list(@wizard, user_id: user.id).size).to eq(1)
end end
end end

Datei anzeigen

@ -34,7 +34,7 @@ describe CustomWizard::Wizard do
template_json['steps'].each do |step_template| template_json['steps'].each do |step_template|
@wizard.append_step(step_template['id']) @wizard.append_step(step_template['id'])
end end
@wizard.update_step_order! @wizard.update!
end end
def progress_step(step_id, acting_user: user, wizard: @wizard) def progress_step(step_id, acting_user: user, wizard: @wizard)
@ -44,7 +44,7 @@ describe CustomWizard::Wizard do
context: wizard.id, context: wizard.id,
subject: step_id subject: step_id
) )
@wizard.update_step_order! @wizard.update!
end end
it "appends steps" do it "appends steps" do
@ -72,7 +72,7 @@ describe CustomWizard::Wizard do
expect(@wizard.steps.first.index).to eq(2) expect(@wizard.steps.first.index).to eq(2)
expect(@wizard.steps.last.index).to eq(0) expect(@wizard.steps.last.index).to eq(0)
@wizard.update_step_order! @wizard.update!
expect(@wizard.steps.first.id).to eq("step_3") expect(@wizard.steps.first.id).to eq("step_3")
expect(@wizard.steps.last.id).to eq("step_1") expect(@wizard.steps.last.id).to eq("step_1")
@ -204,7 +204,7 @@ describe CustomWizard::Wizard do
context "submissions" do context "submissions" do
before do before do
CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission") CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission").save
end end
it "lists the user's submissions" do it "lists the user's submissions" do

Datei anzeigen

@ -6,9 +6,9 @@
"pairs": [ "pairs": [
{ {
"index": 0, "index": 0,
"key": "required_data", "key": "step_1_field_1",
"key_type": "text", "key_type": "text",
"value": "required_value", "value": "required",
"value_type": "text", "value_type": "text",
"connector": "equal" "connector": "equal"
} }

Datei anzeigen

@ -13,11 +13,14 @@ describe CustomWizard::AdminSubmissionsController do
).read) ).read)
} }
let(:template_2) {
temp = template.dup
temp["id"] = "super_mega_fun_wizard_2"
temp
}
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
template_2 = template.dup
template_2["id"] = "super_mega_fun_wizard_2"
CustomWizard::Template.save(template_2, skip_jobs: true) CustomWizard::Template.save(template_2, skip_jobs: true)
wizard1 = CustomWizard::Wizard.create(template["id"], user1) wizard1 = CustomWizard::Wizard.create(template["id"], user1)
@ -33,7 +36,7 @@ describe CustomWizard::AdminSubmissionsController do
it "returns a list of wizards" do it "returns a list of wizards" do
get "/admin/wizards/submissions.json" get "/admin/wizards/submissions.json"
expect(response.parsed_body.length).to eq(3) expect(response.parsed_body.length).to eq(2)
expect(response.parsed_body.first['id']).to eq(template['id']) expect(response.parsed_body.first['id']).to eq(template['id'])
end end

Datei anzeigen

@ -39,8 +39,8 @@ describe ApplicationController do
it "saves original destination of user" do it "saves original destination of user" do
get '/', headers: { 'REFERER' => "/t/2" } get '/', headers: { 'REFERER' => "/t/2" }
expect( expect(
CustomWizard::Wizard.submissions(@template['id'], user) CustomWizard::Wizard.create(@template['id'], user).submissions
.first['redirect_to'] .first.fields['redirect_to']
).to eq("/t/2") ).to eq("/t/2")
end end

Datei anzeigen

@ -175,8 +175,11 @@ describe CustomWizard::StepsController do
wizard_id = response.parsed_body['wizard']['id'] wizard_id = response.parsed_body['wizard']['id']
wizard = CustomWizard::Wizard.create(wizard_id, user) wizard = CustomWizard::Wizard.create(wizard_id, user)
group_name = wizard.current_submission.fields['action_9']
group_name = wizard.submissions.first.fields['action_9']
group = Group.find_by(name: group_name) group = Group.find_by(name: group_name)
expect(group.present?).to eq(true)
expect(group.full_name).to eq("My cool group") expect(group.full_name).to eq("My cool group")
end end

Datei anzeigen

@ -72,7 +72,7 @@ describe CustomWizard::WizardController do
it 'skip response contains a redirect_to if in users submissions' do it 'skip response contains a redirect_to if in users submissions' do
@wizard = CustomWizard::Wizard.create(@template["id"], user) @wizard = CustomWizard::Wizard.create(@template["id"], user)
CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission").save CustomWizard::Submission.new(@wizard, redirect_to: "/t/2").save
put '/w/super-mega-fun-wizard/skip.json' put '/w/super-mega-fun-wizard/skip.json'
expect(response.parsed_body['redirect_to']).to eq('/t/2') expect(response.parsed_body['redirect_to']).to eq('/t/2')
end end