0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-10-18 11:52:39 +02:00

COMPATIBILITY: update linting

Dieser Commit ist enthalten in:
Angus McLeod 2024-10-16 13:52:03 +02:00
Ursprung a163ba56ae
Commit f042f6b9b8
103 geänderte Dateien mit 2736 neuen und 3210 gelöschten Zeilen

Datei anzeigen

@ -1,5 +1,10 @@
inherit_gem: inherit_gem:
rubocop-discourse: default.yml rubocop-discourse: stree-compat.yml
AllCops:
Exclude:
- 'gems/**/*'
- 'vendor/**/*'
RSpec/ContextWording: RSpec/ContextWording:
Enabled: false Enabled: false

2
.streerc Normale Datei
Datei anzeigen

@ -0,0 +1,2 @@
--print-width=100
--plugins=plugin/trailing_comma,plugin/disable_auto_ternary

Datei anzeigen

@ -1,8 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
source 'https://rubygems.org' source "https://rubygems.org"
group :development do group :development do
gem 'rubocop-discourse' gem "rubocop-discourse"
gem 'racc' gem "syntax_tree"
gem "racc"
end end

Datei anzeigen

@ -28,6 +28,7 @@ GEM
parser (3.3.5.0) parser (3.3.5.0)
ast (~> 2.4.1) ast (~> 2.4.1)
racc racc
prettier_print (1.2.1)
racc (1.8.1) racc (1.8.1)
rack (3.1.7) rack (3.1.7)
rainbow (3.1.1) rainbow (3.1.1)
@ -68,6 +69,8 @@ GEM
rubocop-rspec (~> 3, >= 3.0.1) rubocop-rspec (~> 3, >= 3.0.1)
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
securerandom (0.3.1) securerandom (0.3.1)
syntax_tree (6.2.0)
prettier_print (>= 1.2.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
unicode-display_width (2.6.0) unicode-display_width (2.6.0)
@ -79,6 +82,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
racc racc
rubocop-discourse rubocop-discourse
syntax_tree
BUNDLED WITH BUNDLED WITH
2.5.18 2.5.18

Datei anzeigen

@ -3,21 +3,28 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
skip_before_action :check_xhr, only: [:redirect] skip_before_action :check_xhr, only: [:redirect]
def list def list
serializer = ActiveModel::ArraySerializer.new(CustomWizard::Api.list, serializer =
each_serializer: CustomWizard::BasicApiSerializer ActiveModel::ArraySerializer.new(
) CustomWizard::Api.list,
each_serializer: CustomWizard::BasicApiSerializer,
)
render json: MultiJson.dump(serializer) render json: MultiJson.dump(serializer)
end end
def find def find
render_serialized(CustomWizard::Api.get(api_params[:name]), CustomWizard::ApiSerializer, root: false) render_serialized(
CustomWizard::Api.get(api_params[:name]),
CustomWizard::ApiSerializer,
root: false,
)
end end
def save def save
current = CustomWizard::Api.get(api_params[:name]) current = CustomWizard::Api.get(api_params[:name])
if api_params[:new] && current if api_params[:new] && current
raise Discourse::InvalidParameters, "An API with that name already exists: '#{current.title || current.name}'" raise Discourse::InvalidParameters,
"An API with that name already exists: '#{current.title || current.name}'"
end end
unless subscription.includes?(:api, :all) unless subscription.includes?(:api, :all)
@ -28,28 +35,28 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
CustomWizard::Api.set(api_params[:name], title: api_params[:title]) CustomWizard::Api.set(api_params[:name], title: api_params[:title])
if auth_data.present? if auth_data.present?
auth_data['auth_params'] = auth_data['auth_params'] || [] auth_data["auth_params"] = auth_data["auth_params"] || []
CustomWizard::Api::Authorization.set(api_params[:name], auth_data) CustomWizard::Api::Authorization.set(api_params[:name], auth_data)
end end
if api_params[:endpoints].is_a? String if api_params[:endpoints].is_a? String
begin begin
endpoints = JSON.parse(api_params[:endpoints]) endpoints = JSON.parse(api_params[:endpoints])
endpoints.each do |endpoint| endpoints.each { |endpoint| CustomWizard::Api::Endpoint.set(api_params[:name], endpoint) }
CustomWizard::Api::Endpoint.set(api_params[:name], endpoint)
end
rescue => e rescue => e
puts e puts e
end end
end end
end end
render json: success_json.merge( render json:
api: CustomWizard::ApiSerializer.new( success_json.merge(
CustomWizard::Api.get(api_params[:name]), api:
root: false CustomWizard::ApiSerializer.new(
) CustomWizard::Api.get(api_params[:name]),
) root: false,
),
)
end end
def remove def remove
@ -67,14 +74,16 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
result = CustomWizard::Api::Authorization.get_token(api_params[:name]) result = CustomWizard::Api::Authorization.get_token(api_params[:name])
if result.instance_variable_defined?(:@error) if result.instance_variable_defined?(:@error)
render json: failed_json.merge(message: result['error_description'] || result['error']) render json: failed_json.merge(message: result["error_description"] || result["error"])
else else
render json: success_json.merge( render json:
api: CustomWizard::ApiSerializer.new( success_json.merge(
CustomWizard::Api.get(api_params[:name]), api:
root: false CustomWizard::ApiSerializer.new(
) CustomWizard::Api.get(api_params[:name]),
) root: false,
),
)
end end
end end
@ -90,7 +99,7 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
CustomWizard::Api::Authorization.set(params[:name], code: params[:code]) CustomWizard::Api::Authorization.set(params[:name], code: params[:code])
CustomWizard::Api::Authorization.get_token(params[:name]) CustomWizard::Api::Authorization.get_token(params[:name])
redirect_to path('/admin/wizards/apis/' + params[:name]) redirect_to path("/admin/wizards/apis/" + params[:name])
end end
private private
@ -98,20 +107,21 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
def api_params def api_params
params.require(:name) params.require(:name)
data = params.permit( data =
:name, params.permit(
:title, :name,
:auth_type, :title,
:auth_url, :auth_type,
:token_url, :auth_url,
:client_id, :token_url,
:client_secret, :client_id,
:username, :client_secret,
:password, :username,
:auth_params, :password,
:endpoints, :auth_params,
:new :endpoints,
).to_h :new,
).to_h
data[:name] = data[:name].underscore data[:name] = data[:name].underscore
@ -119,18 +129,21 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
end end
def auth_data def auth_data
auth_data = api_params.slice( auth_data =
:auth_type, api_params.slice(
:auth_url, :auth_type,
:token_url, :auth_url,
:client_id, :token_url,
:client_secret, :client_id,
:username, :client_secret,
:password, :username,
:auth_params :password,
) :auth_params,
)
auth_data[:auth_params] = JSON.parse(auth_data[:auth_params]) if auth_data[:auth_params].present? auth_data[:auth_params] = JSON.parse(auth_data[:auth_params]) if auth_data[
:auth_params
].present?
@auth_data ||= auth_data @auth_data ||= auth_data
end end

Datei anzeigen

@ -1,9 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
def index def index
render_json_dump( render_json_dump(custom_fields: custom_field_list)
custom_fields: custom_field_list
)
end end
def update def update
@ -12,23 +10,24 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
field_data = {} field_data = {}
if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i) if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i)
CustomWizard::CustomField::ATTRS.each do |attr| CustomWizard::CustomField::ATTRS.each { |attr| field_data[attr] = saved_field.send(attr) }
field_data[attr] = saved_field.send(attr)
end
field_id = saved_field.id field_id = saved_field.id
end end
CustomWizard::CustomField::ATTRS.each do |attr| CustomWizard::CustomField::ATTRS.each { |attr| field_data[attr] = field_params[attr] }
field_data[attr] = field_params[attr]
end
field = CustomWizard::CustomField.new(field_id, field_data) field = CustomWizard::CustomField.new(field_id, field_data)
PluginStoreRow.transaction do PluginStoreRow.transaction do
unless field.save unless field.save
field_errors = field.errors.any? ? field_errors =
field.errors.full_messages.join("\n\n") : (
I18n.t("wizard.custom_field.error.save_default", name: field.name) if field.errors.any?
field.errors.full_messages.join("\n\n")
else
I18n.t("wizard.custom_field.error.save_default", name: field.name)
end
)
errors << field_errors errors << field_errors
raise ActiveRecord::Rollback.new raise ActiveRecord::Rollback.new
end end
@ -54,13 +53,6 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
private private
def field_params def field_params
params.required(:custom_field) params.required(:custom_field).permit(:id, :name, :klass, :type, serializers: [])
.permit(
:id,
:name,
:klass,
:type,
serializers: []
)
end end
end end

Datei anzeigen

@ -3,42 +3,45 @@ class CustomWizard::AdminLogsController < CustomWizard::AdminController
before_action :find_wizard, except: [:index] before_action :find_wizard, except: [:index]
def index def index
render json: ActiveModel::ArraySerializer.new( render json:
CustomWizard::Wizard.list(current_user), ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::BasicWizardSerializer CustomWizard::Wizard.list(current_user),
) each_serializer: CustomWizard::BasicWizardSerializer,
)
end end
def show def show
render_json_dump( render_json_dump(
wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false), wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false),
logs: ActiveModel::ArraySerializer.new( logs:
log_list.logs, ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::LogSerializer log_list.logs,
), each_serializer: CustomWizard::LogSerializer,
total: log_list.total ),
total: log_list.total,
) )
end end
protected protected
def log_list def log_list
@log_list ||= begin @log_list ||=
list = CustomWizard::Log.list(params[:page].to_i, params[:limit].to_i, params[:wizard_id]) begin
list = CustomWizard::Log.list(params[:page].to_i, params[:limit].to_i, params[:wizard_id])
if list.logs.any? && (usernames = list.logs.map(&:username)).present? if list.logs.any? && (usernames = list.logs.map(&:username)).present?
user_map = User.where(username: usernames) user_map =
.reduce({}) do |result, user| User
result[user.username] = user .where(username: usernames)
result .reduce({}) do |result, user|
end result[user.username] = user
result
end
list.logs.each do |log_item| list.logs.each { |log_item| log_item.user = user_map[log_item.username] }
log_item.user = user_map[log_item.username]
end end
end
list list
end end
end end
end end

Datei anzeigen

@ -12,38 +12,32 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
end end
end end
if templates.empty? return render_error(I18n.t("wizard.export.error.invalid_wizards")) if templates.empty?
return render_error(I18n.t('wizard.export.error.invalid_wizards'))
end
basename = SiteSetting.title.parameterize || 'discourse' basename = SiteSetting.title.parameterize || "discourse"
time = Time.now.to_i time = Time.now.to_i
filename = "#{basename}-wizards-#{time}.json" filename = "#{basename}-wizards-#{time}.json"
send_data templates.to_json, send_data templates.to_json,
type: "application/json", type: "application/json",
disposition: 'attachment', disposition: "attachment",
filename: filename filename: filename
end end
def import def import
file = File.read(params['file'].tempfile) file = File.read(params["file"].tempfile)
if file.nil? return render_error(I18n.t("wizard.export.error.no_file")) if file.nil?
return render_error(I18n.t('wizard.export.error.no_file'))
end
file_size = file.size file_size = file.size
max_file_size = 512 * 1024 max_file_size = 512 * 1024
if max_file_size < file_size return render_error(I18n.t("wizard.import.error.file_large")) if max_file_size < file_size
return render_error(I18n.t('wizard.import.error.file_large'))
end
begin begin
template_json = JSON.parse(file) template_json = JSON.parse(file)
rescue JSON::ParserError rescue JSON::ParserError
return render_error(I18n.t('wizard.import.error.invalid_json')) return render_error(I18n.t("wizard.import.error.invalid_json"))
end end
imported = [] imported = []
@ -55,22 +49,13 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
template.save(skip_jobs: true, create: true) template.save(skip_jobs: true, create: true)
if template.errors.any? if template.errors.any?
failures.push( failures.push(id: template.data["id"], messages: template.errors.full_messages.join(", "))
id: template.data['id'],
messages: template.errors.full_messages.join(', ')
)
else else
imported.push( imported.push(id: template.data["id"], name: template.data["name"])
id: template.data['id'],
name: template.data['name']
)
end end
end end
render json: success_json.merge( render json: success_json.merge(imported: imported, failures: failures)
imported: imported,
failures: failures
)
end end
def destroy def destroy
@ -81,44 +66,34 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
template = CustomWizard::Template.find(wizard_id) template = CustomWizard::Template.find(wizard_id)
if template && CustomWizard::Template.remove(wizard_id) if template && CustomWizard::Template.remove(wizard_id)
destroyed.push( destroyed.push(id: wizard_id, name: template["name"])
id: wizard_id,
name: template['name']
)
else else
failures.push( failures.push(
id: wizard_id, id: wizard_id,
messages: I18n.t("wizard.destroy.error.#{template ? 'default' : 'no_template'}") messages: I18n.t("wizard.destroy.error.#{template ? "default" : "no_template"}"),
) )
end end
end end
render json: success_json.merge( render json: success_json.merge(destroyed: destroyed, failures: failures)
destroyed: destroyed,
failures: failures
)
end end
private private
def get_wizard_ids def get_wizard_ids
if params['wizard_ids'].blank? return render_error(I18n.t("wizard.export.error.select_one")) if params["wizard_ids"].blank?
return render_error(I18n.t('wizard.export.error.select_one'))
end
wizard_ids = [] wizard_ids = []
params['wizard_ids'].each do |wizard_id| params["wizard_ids"].each do |wizard_id|
begin begin
wizard_ids.push(wizard_id.underscore) wizard_ids.push(wizard_id.underscore)
rescue rescue StandardError
# #
end end
end end
if wizard_ids.empty? return render_error(I18n.t("wizard.export.error.invalid_wizards")) if wizard_ids.empty?
return render_error(I18n.t('wizard.export.error.invalid_wizards'))
end
@wizard_ids = wizard_ids @wizard_ids = wizard_ids
end end

Datei anzeigen

@ -4,33 +4,36 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
before_action :find_wizard, except: [:index] before_action :find_wizard, except: [:index]
def index def index
render json: ActiveModel::ArraySerializer.new( render json:
CustomWizard::Wizard.list(current_user), ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::BasicWizardSerializer CustomWizard::Wizard.list(current_user),
) each_serializer: CustomWizard::BasicWizardSerializer,
)
end end
def show def show
render_json_dump( render_json_dump(
wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false), wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false),
submissions: ActiveModel::ArraySerializer.new( submissions:
submission_list.submissions, ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::SubmissionSerializer submission_list.submissions,
), each_serializer: CustomWizard::SubmissionSerializer,
total: submission_list.total ),
total: submission_list.total,
) )
end end
def download def download
content = ActiveModel::ArraySerializer.new( content =
CustomWizard::Submission.list(@wizard).submissions, ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::SubmissionSerializer CustomWizard::Submission.list(@wizard).submissions,
) each_serializer: CustomWizard::SubmissionSerializer,
)
send_data content.to_json, send_data content.to_json,
filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json", filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json",
content_type: "application/json", content_type: "application/json",
disposition: "attachment" disposition: "attachment"
end end
protected protected

Datei anzeigen

@ -1,16 +1,17 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::AdminWizardController < CustomWizard::AdminController class CustomWizard::AdminWizardController < CustomWizard::AdminController
before_action :find_wizard, only: [:show, :remove] before_action :find_wizard, only: %i[show remove]
def index def index
render_json_dump( render_json_dump(
wizard_list: ActiveModel::ArraySerializer.new( wizard_list:
CustomWizard::Wizard.list(current_user), ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::BasicWizardSerializer CustomWizard::Wizard.list(current_user),
), each_serializer: CustomWizard::BasicWizardSerializer,
),
field_types: CustomWizard::Field.types, field_types: CustomWizard::Field.types,
realtime_validations: CustomWizard::RealtimeValidation.types, realtime_validations: CustomWizard::RealtimeValidation.types,
custom_fields: custom_field_list custom_fields: custom_field_list,
) )
end end
@ -37,7 +38,10 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
wizard_id = template.save(create: params[:create]) wizard_id = template.save(create: params[:create])
if template.errors.any? if template.errors.any?
render json: failed_json.merge(backend_validation_error: template.errors.full_messages.join("\n\n")) render json:
failed_json.merge(
backend_validation_error: template.errors.full_messages.join("\n\n"),
)
else else
render json: success_json.merge(wizard_id: wizard_id) render json: success_json.merge(wizard_id: wizard_id)
end end
@ -52,16 +56,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
:output, :output,
:output_type, :output_type,
:output_connector, :output_connector,
pairs: [ pairs: [:index, :key, :key_type, :value, :value_type, :connector, value: [], key: []],
:index,
:key,
:key_type,
:value,
:value_type,
:connector,
value: [],
key: [],
],
output: [], output: [],
] ]
end end
@ -120,9 +115,10 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
content: mapped_params, content: mapped_params,
condition: mapped_params, condition: mapped_params,
index: mapped_params, index: mapped_params,
validations: {}, validations: {
},
tag_groups: [], tag_groups: [],
] ],
], ],
actions: [ actions: [
:id, :id,
@ -169,8 +165,8 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
visibility_level: mapped_params, visibility_level: mapped_params,
members_visibility_level: mapped_params, members_visibility_level: mapped_params,
add_event: mapped_params, add_event: mapped_params,
add_location: mapped_params add_location: mapped_params,
] ],
) )
end end
end end

Datei anzeigen

@ -8,9 +8,7 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
update[:fields] = {} update[:fields] = {}
if params[:fields] if params[:fields]
field_ids = @builder.wizard.field_ids field_ids = @builder.wizard.field_ids
params[:fields].each do |k, v| params[:fields].each { |k, v| update[:fields][k] = v if field_ids.include? k }
update[:fields][k] = v if field_ids.include? k
end
end end
@builder.build @builder.build
@ -34,16 +32,15 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
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"
action_result = CustomWizard::Action.new( action_result =
action: action_template, CustomWizard::Action.new(
wizard: @wizard, action: action_template,
submission: current_submission wizard: @wizard,
).perform submission: current_submission,
).perform
if action_result.success? current_submission = action_result.submission if action_result.success?
current_submission = action_result.submission
end
end end
end end
@ -68,14 +65,14 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
result[:wizard] = ::CustomWizard::WizardSerializer.new( result[:wizard] = ::CustomWizard::WizardSerializer.new(
@wizard, @wizard,
scope: Guardian.new(current_user), scope: Guardian.new(current_user),
root: false root: false,
).as_json ).as_json
render json: result render json: result
else else
errors = [] errors = []
updater.errors.messages.each do |field, msg| updater.errors.messages.each do |field, msg|
errors << { field: field, description: msg.join(',') } errors << { field: field, description: msg.join(",") }
end end
render json: { errors: errors }, status: 422 render json: { errors: errors }, status: 422
end end
@ -87,26 +84,25 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
raise Discourse::InvalidParameters.new(:wizard_id) if @builder.template.nil? raise Discourse::InvalidParameters.new(:wizard_id) if @builder.template.nil?
raise Discourse::InvalidAccess.new if !@builder.wizard || !@builder.wizard.can_access? raise Discourse::InvalidAccess.new if !@builder.wizard || !@builder.wizard.can_access?
@step_template = @builder.template.steps.select do |s| @step_template = @builder.template.steps.select { |s| s["id"] == update_params[:step_id] }.first
s['id'] == update_params[:step_id]
end.first
raise Discourse::InvalidParameters.new(:step_id) if !@step_template raise Discourse::InvalidParameters.new(:step_id) if !@step_template
raise Discourse::InvalidAccess.new if !@builder.check_condition(@step_template) raise Discourse::InvalidAccess.new if !@builder.check_condition(@step_template)
end end
def update_params def update_params
@update_params || begin @update_params ||
params.require(:step_id) begin
params.require(:wizard_id) params.require(:step_id)
params.permit(:wizard_id, :step_id).transform_values { |v| v.underscore } params.require(:wizard_id)
end params.permit(:wizard_id, :step_id).transform_values { |v| v.underscore }
end
end end
def get_redirect def get_redirect
return @result[:redirect_on_next] if @result[:redirect_on_next].present? return @result[:redirect_on_next] if @result[:redirect_on_next].present?
submission = @wizard.current_submission submission = @wizard.current_submission
return nil unless submission.present? return nil if submission.blank?
## route_to set by actions, redirect_on_complete set by actions, redirect_to set at wizard entry ## route_to set by actions, redirect_on_complete set by actions, redirect_to set at wizard entry
submission.route_to || submission.redirect_on_complete || submission.redirect_to submission.route_to || submission.redirect_on_complete || submission.redirect_to
end end

Datei anzeigen

@ -2,9 +2,10 @@
class CustomWizard::WizardController < ::CustomWizard::WizardClientController class CustomWizard::WizardController < ::CustomWizard::WizardClientController
def show def show
if wizard.present? if wizard.present?
render json: CustomWizard::WizardSerializer.new(wizard, scope: guardian, root: false).as_json, status: 200 render json: CustomWizard::WizardSerializer.new(wizard, scope: guardian, root: false).as_json,
status: 200
else else
render json: { error: I18n.t('wizard.none') } render json: { error: I18n.t("wizard.none") }
end end
end end
@ -12,10 +13,10 @@ class CustomWizard::WizardController < ::CustomWizard::WizardClientController
params.require(:wizard_id) params.require(:wizard_id)
if wizard.required && !wizard.completed? && wizard.permitted? if wizard.required && !wizard.completed? && wizard.permitted?
return render json: { error: I18n.t('wizard.no_skip') } return render json: { error: I18n.t("wizard.no_skip") }
end end
result = { success: 'OK' } result = { success: "OK" }
if current_user && wizard.can_access? if current_user && wizard.can_access?
if redirect_to = wizard.current_submission&.redirect_to if redirect_to = wizard.current_submission&.redirect_to
@ -31,9 +32,10 @@ class CustomWizard::WizardController < ::CustomWizard::WizardClientController
protected protected
def wizard def wizard
@wizard ||= begin @wizard ||=
return nil unless @builder.present? begin
@builder.build({ reset: params[:reset] }, params) return nil if @builder.blank?
end @builder.build({ reset: params[:reset] }, params)
end
end end
end end

Datei anzeigen

@ -6,9 +6,7 @@ class CustomWizard::WizardClientController < ::ApplicationController
private private
def ensure_plugin_enabled def ensure_plugin_enabled
unless SiteSetting.custom_wizard_enabled redirect_to path("/") unless SiteSetting.custom_wizard_enabled
redirect_to path("/")
end
end end
def guest_id def guest_id

Datei anzeigen

@ -9,9 +9,7 @@ module Jobs
user_ids = [] user_ids = []
User.human_users.each do |user| User.human_users.each do |user|
if CustomWizard::Wizard.set_user_redirect(wizard.id, user) user_ids.push(user.id) if CustomWizard::Wizard.set_user_redirect(wizard.id, user)
user_ids.push(user.id)
end
end end
CustomWizard::Template.clear_cache_keys CustomWizard::Template.clear_cache_keys

Datei anzeigen

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::Api::BasicEndpointSerializer < ::ApplicationSerializer class CustomWizard::Api::BasicEndpointSerializer < ::ApplicationSerializer
attributes :id, attributes :id, :name
:name
end end

Datei anzeigen

@ -1,13 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::Api::EndpointSerializer < ::ApplicationSerializer class CustomWizard::Api::EndpointSerializer < ::ApplicationSerializer
attributes :id, attributes :id, :name, :method, :url, :content_type, :success_codes
:name,
:method,
:url,
:content_type,
:success_codes
def method def method
object.send('method') object.send("method")
end end
end end

Datei anzeigen

@ -1,35 +1,25 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::ApiSerializer < ::ApplicationSerializer class CustomWizard::ApiSerializer < ::ApplicationSerializer
attributes :name, attributes :name, :title, :authorization, :endpoints, :log
:title,
:authorization,
:endpoints,
:log
def authorization def authorization
if authorization = CustomWizard::Api::Authorization.get(object.name) if authorization = CustomWizard::Api::Authorization.get(object.name)
CustomWizard::Api::AuthorizationSerializer.new( CustomWizard::Api::AuthorizationSerializer.new(authorization, root: false)
authorization,
root: false
)
end end
end end
def endpoints def endpoints
if endpoints = CustomWizard::Api::Endpoint.list(object.name) if endpoints = CustomWizard::Api::Endpoint.list(object.name)
ActiveModel::ArraySerializer.new( ActiveModel::ArraySerializer.new(
endpoints, endpoints,
each_serializer: CustomWizard::Api::EndpointSerializer each_serializer: CustomWizard::Api::EndpointSerializer,
) )
end end
end end
def log def log
if log = CustomWizard::Api::LogEntry.list(object.name) if log = CustomWizard::Api::LogEntry.list(object.name)
ActiveModel::ArraySerializer.new( ActiveModel::ArraySerializer.new(log, each_serializer: CustomWizard::Api::LogSerializer)
log,
each_serializer: CustomWizard::Api::LogSerializer
)
end end
end end
end end

Datei anzeigen

@ -1,14 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::BasicApiSerializer < ::ApplicationSerializer class CustomWizard::BasicApiSerializer < ::ApplicationSerializer
attributes :name, attributes :name, :title, :endpoints
:title,
:endpoints
def endpoints def endpoints
if endpoints = CustomWizard::Api::Endpoint.list(object.name) if endpoints = CustomWizard::Api::Endpoint.list(object.name)
ActiveModel::ArraySerializer.new( ActiveModel::ArraySerializer.new(
endpoints, endpoints,
each_serializer: CustomWizard::Api::BasicEndpointSerializer each_serializer: CustomWizard::Api::BasicEndpointSerializer,
) )
end end
end end

Datei anzeigen

@ -1,10 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::LogSerializer < ApplicationSerializer class CustomWizard::LogSerializer < ApplicationSerializer
attributes :date, attributes :date, :action, :username, :message
:action,
:username,
:message
has_one :user, serializer: ::BasicUserSerializer, embed: :objects has_one :user, serializer: ::BasicUserSerializer, embed: :objects
end end

Datei anzeigen

@ -1,9 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::SubmissionSerializer < ApplicationSerializer class CustomWizard::SubmissionSerializer < ApplicationSerializer
attributes :id, attributes :id, :fields, :submitted_at, :user
:fields,
:submitted_at,
:user
def include_user? def include_user?
object.wizard.user.present? object.wizard.user.present?
@ -14,22 +11,19 @@ class CustomWizard::SubmissionSerializer < ApplicationSerializer
end end
def fields def fields
@fields ||= begin @fields ||=
result = {} begin
result = {}
object.wizard.template['steps'].each do |step| object.wizard.template["steps"].each do |step|
step['fields'].each do |field| step["fields"].each do |field|
if value = object.fields[field['id']] if value = object.fields[field["id"]]
result[field['id']] = { result[field["id"]] = { value: value, type: field["type"], label: field["label"] }
value: value, end
type: field['type'], end
label: field['label'] end
}
end
end
end
result result
end end
end end
end end

Datei anzeigen

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::FieldSerializer < ::ApplicationSerializer class CustomWizard::FieldSerializer < ::ApplicationSerializer
attributes :id, attributes :id,
:index, :index,
:type, :type,
@ -109,7 +108,9 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
object.validations&.each do |type, props| object.validations&.each do |type, props|
next unless props["status"] next unless props["status"]
validations[props["position"]] ||= {} validations[props["position"]] ||= {}
validations[props["position"]][type] = props.merge CustomWizard::RealtimeValidation.types[type.to_sym] validations[props["position"]][type] = props.merge CustomWizard::RealtimeValidation.types[
type.to_sym
]
end end
validations validations

Datei anzeigen

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
attributes :start, attributes :start,
:background, :background,
:submission_last_updated_at, :submission_last_updated_at,
@ -20,8 +19,8 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
def include_completed? def include_completed?
object.completed? && object.completed? &&
(!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) && (!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) &&
!scope.is_admin? !scope.is_admin?
end end
def permitted def permitted

Datei anzeigen

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::StepSerializer < ::ApplicationSerializer class CustomWizard::StepSerializer < ::ApplicationSerializer
attributes :id, attributes :id,
:index, :index,
:next, :next,

Datei anzeigen

@ -1,49 +1,49 @@
# frozen_string_literal: true # frozen_string_literal: true
CustomWizard::Engine.routes.draw do CustomWizard::Engine.routes.draw do
get ':wizard_id' => 'wizard#show' get ":wizard_id" => "wizard#show"
put ':wizard_id/skip' => 'wizard#skip' put ":wizard_id/skip" => "wizard#skip"
get ':wizard_id/steps' => 'wizard#show' get ":wizard_id/steps" => "wizard#show"
get ':wizard_id/steps/:step_id' => 'wizard#show' get ":wizard_id/steps/:step_id" => "wizard#show"
put ':wizard_id/steps/:step_id' => 'steps#update' put ":wizard_id/steps/:step_id" => "steps#update"
end end
Discourse::Application.routes.append do Discourse::Application.routes.append do
mount ::CustomWizard::Engine, at: 'w' mount ::CustomWizard::Engine, at: "w"
post 'wizard/authorization/callback' => "custom_wizard/authorization#callback" post "wizard/authorization/callback" => "custom_wizard/authorization#callback"
get 'realtime-validations' => 'custom_wizard/realtime_validations#validate' get "realtime-validations" => "custom_wizard/realtime_validations#validate"
scope module: 'custom_wizard', constraints: AdminConstraint.new do scope module: "custom_wizard", constraints: AdminConstraint.new do
get 'admin/wizards' => 'admin#index' get "admin/wizards" => "admin#index"
get 'admin/wizards/subscription' => 'subscription#index' get "admin/wizards/subscription" => "subscription#index"
get 'admin/wizards/wizard' => 'admin_wizard#index' get "admin/wizards/wizard" => "admin_wizard#index"
get 'admin/wizards/wizard/create' => 'admin#index' get "admin/wizards/wizard/create" => "admin#index"
get 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#show' get "admin/wizards/wizard/:wizard_id" => "admin_wizard#show"
put 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#save' put "admin/wizards/wizard/:wizard_id" => "admin_wizard#save"
delete 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#remove' delete "admin/wizards/wizard/:wizard_id" => "admin_wizard#remove"
get 'admin/wizards/custom-fields' => 'admin_custom_fields#index' get "admin/wizards/custom-fields" => "admin_custom_fields#index"
put 'admin/wizards/custom-fields' => 'admin_custom_fields#update' put "admin/wizards/custom-fields" => "admin_custom_fields#update"
delete 'admin/wizards/custom-fields/:name' => 'admin_custom_fields#destroy' delete "admin/wizards/custom-fields/:name" => "admin_custom_fields#destroy"
get 'admin/wizards/submissions' => 'admin_submissions#index' get "admin/wizards/submissions" => "admin_submissions#index"
get 'admin/wizards/submissions/:wizard_id' => 'admin_submissions#show' get "admin/wizards/submissions/:wizard_id" => "admin_submissions#show"
get 'admin/wizards/submissions/:wizard_id/download' => 'admin_submissions#download' get "admin/wizards/submissions/:wizard_id/download" => "admin_submissions#download"
get 'admin/wizards/api' => 'admin_api#list' get "admin/wizards/api" => "admin_api#list"
get 'admin/wizards/api/:name' => 'admin_api#find' get "admin/wizards/api/:name" => "admin_api#find"
put 'admin/wizards/api/:name' => 'admin_api#save' put "admin/wizards/api/:name" => "admin_api#save"
delete 'admin/wizards/api/:name' => 'admin_api#remove' delete "admin/wizards/api/:name" => "admin_api#remove"
delete 'admin/wizards/api/:name/logs' => 'admin_api#clearlogs' delete "admin/wizards/api/:name/logs" => "admin_api#clearlogs"
get 'admin/wizards/api/:name/redirect' => 'admin_api#redirect' get "admin/wizards/api/:name/redirect" => "admin_api#redirect"
get 'admin/wizards/api/:name/authorize' => 'admin_api#authorize' get "admin/wizards/api/:name/authorize" => "admin_api#authorize"
get 'admin/wizards/logs' => 'admin_logs#index' get "admin/wizards/logs" => "admin_logs#index"
get 'admin/wizards/logs/:wizard_id' => 'admin_logs#show' get "admin/wizards/logs/:wizard_id" => "admin_logs#show"
get 'admin/wizards/manager' => 'admin_manager#index' get "admin/wizards/manager" => "admin_manager#index"
get 'admin/wizards/manager/export' => 'admin_manager#export' get "admin/wizards/manager/export" => "admin_manager#export"
post 'admin/wizards/manager/import' => 'admin_manager#import' post "admin/wizards/manager/import" => "admin_manager#import"
delete 'admin/wizards/manager/destroy' => 'admin_manager#destroy' delete "admin/wizards/manager/destroy" => "admin_manager#destroy"
end end
end end

Datei anzeigen

@ -1,10 +1,13 @@
# frozen_string_literal: true # frozen_string_literal: true
class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0] class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0]
def change def change
watch_category_wizards = PluginStoreRow.where(" watch_category_wizards =
PluginStoreRow.where(
"
plugin_name = 'custom_wizard' AND plugin_name = 'custom_wizard' AND
value::jsonb -> 'actions' @> '[{ \"type\" : \"watch_categories\" }]'::jsonb value::jsonb -> 'actions' @> '[{ \"type\" : \"watch_categories\" }]'::jsonb
") ",
)
if watch_category_wizards.exists? if watch_category_wizards.exists?
watch_category_wizards.each do |row| watch_category_wizards.each do |row|
@ -14,10 +17,8 @@ class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0]
next next
end end
wizard_json['actions'].each do |a| wizard_json["actions"].each do |a|
if a['type'] === "watch_categories" && a['wizard_user'] == nil a["wizard_user"] = true if a["type"] === "watch_categories" && a["wizard_user"] == nil
a['wizard_user'] = true
end
end end
row.value = wizard_json.to_json row.value = wizard_json.to_json

Datei anzeigen

@ -5,7 +5,7 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
action: "action", action: "action",
user: "username", user: "username",
date: "date", date: "date",
message: "message" message: "message",
} }
def change def change
@ -23,22 +23,21 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
next next
end end
if log_json.key?('message') && log_json['message'].is_a?(String) if log_json.key?("message") && log_json["message"].is_a?(String)
attr_strs = [] attr_strs = []
# assumes no whitespace in the values # assumes no whitespace in the values
attr_strs << log_json['message'].slice!(/(wizard: \S*; )/, 1) attr_strs << log_json["message"].slice!(/(wizard: \S*; )/, 1)
attr_strs << log_json['message'].slice!(/(action: \S*; )/, 1) attr_strs << log_json["message"].slice!(/(action: \S*; )/, 1)
attr_strs << log_json['message'].slice!(/(user: \S*; )/, 1) attr_strs << log_json["message"].slice!(/(user: \S*; )/, 1)
attr_strs.each do |attr_str| attr_strs.each do |attr_str|
if attr_str.is_a? String if attr_str.is_a? String
attr_str.gsub!(/[;]/ , "") attr_str.gsub!(/[;]/, "")
key, value = attr_str.split(': ') key, value = attr_str.split(": ")
value.strip! if value value.strip! if value
key = KEY_MAP[key.to_sym] ? KEY_MAP[key.to_sym] : key key = KEY_MAP[key.to_sym] ? KEY_MAP[key.to_sym] : key
log_json[key] = value ? value : '' log_json[key] = value ? value : ""
end end
end end
@ -61,22 +60,25 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
end end
# concatenate wizard/action/user to start of message # concatenate wizard/action/user to start of message
prefixes = log_json.extract!('wizard_id', 'action', 'username') prefixes = log_json.extract!("wizard_id", "action", "username")
message_prefix = "" message_prefix = ""
if prefixes.present? if prefixes.present?
message_prefix = prefixes.map do |k, v| message_prefix =
key = KEY_MAP.key(k) ? KEY_MAP.key(k) : k prefixes
"#{key.to_s}: #{v};" .map do |k, v|
end.join(' ') key = KEY_MAP.key(k) ? KEY_MAP.key(k) : k
"#{key}: #{v};"
end
.join(" ")
end end
if log_json.key?('message') if log_json.key?("message")
message = log_json['message'] message = log_json["message"]
message = "#{message_prefix} #{message}" if message_prefix.present? message = "#{message_prefix} #{message}" if message_prefix.present?
log_json['message'] = message log_json["message"] = message
else else
log_json['message'] = message_prefix log_json["message"] = message_prefix
end end
row.value = log_json.to_json row.value = log_json.to_json

Datei anzeigen

@ -1,19 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::Action class CustomWizard::Action
attr_accessor :submission, attr_accessor :submission, :action, :user, :guardian, :result
:action,
:user,
:guardian,
:result
REQUIRES_USER = %w[ REQUIRES_USER = %w[update_profile open_composer watch_categories add_to_group]
update_profile
open_composer
watch_categories
add_to_group
]
WIZARD_USER = 'wizard-user' WIZARD_USER = "wizard-user"
def initialize(opts) def initialize(opts)
@wizard = opts[:wizard] @wizard = opts[:wizard]
@ -26,23 +17,17 @@ class CustomWizard::Action
end end
def perform def perform
if REQUIRES_USER.include?(action['id']) && !@user if REQUIRES_USER.include?(action["id"]) && !@user
log_error("action requires user", "id: #{action['id']};") log_error("action requires user", "id: #{action["id"]};")
@result.success = false @result.success = false
return @result return @result
end end
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction { self.send(action["type"].to_sym) }
self.send(action['type'].to_sym)
end
if creates_post? && @result.success? @result.handler.enqueue_jobs if creates_post? && @result.success?
@result.handler.enqueue_jobs
end
if @result.success? && @result.output.present? @submission.fields[action["id"]] = @result.output if @result.success? && @result.output.present?
@submission.fields[action['id']] = @result.output
end
save_log save_log
@ -76,7 +61,7 @@ class CustomWizard::Action
if creator.errors.present? if creator.errors.present?
messages = creator.errors.full_messages.join(" ") messages = creator.errors.full_messages.join(" ")
log_error("failed to create", messages) log_error("failed to create", messages)
elsif action['skip_redirect'].blank? elsif action["skip_redirect"].blank?
@submission.redirect_on_complete = post.topic.url @submission.redirect_on_complete = post.topic.url
end end
@ -91,12 +76,9 @@ class CustomWizard::Action
end end
def send_message def send_message
if action['required'].present? if action["required"].present?
required = CustomWizard::Mapper.new( required =
inputs: action['required'], CustomWizard::Mapper.new(inputs: action["required"], data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
if required.blank? if required.blank?
log_error("required input not present") log_error("required input not present")
@ -106,12 +88,13 @@ class CustomWizard::Action
params = basic_topic_params params = basic_topic_params
targets = CustomWizard::Mapper.new( targets =
inputs: action['recipient'], CustomWizard::Mapper.new(
data: mapper_data, inputs: action["recipient"],
user: user, data: mapper_data,
multiple: true user: user,
).perform multiple: true,
).perform
if targets.blank? if targets.blank?
log_error("no recipients", "send_message has no recipients") log_error("no recipients", "send_message has no recipients")
@ -131,12 +114,11 @@ class CustomWizard::Action
end end
end end
if params[:title].present? && if params[:title].present? && params[:raw].present? &&
params[:raw].present? && (
(params[:target_usernames].present? || params[:target_usernames].present? || params[:target_group_names].present? ||
params[:target_group_names].present? || params[:target_emails].present?
params[:target_emails].present?) )
params[:archetype] = Archetype.private_message params[:archetype] = Archetype.private_message
creator = PostCreator.new(topic_poster, params) creator = PostCreator.new(topic_poster, params)
@ -145,7 +127,7 @@ class CustomWizard::Action
if creator.errors.present? if creator.errors.present?
messages = creator.errors.full_messages.join(" ") messages = creator.errors.full_messages.join(" ")
log_error("failed to create message", messages) log_error("failed to create message", messages)
elsif user && action['skip_redirect'].blank? elsif user && action["skip_redirect"].blank?
@submission.redirect_on_complete = post.topic.url @submission.redirect_on_complete = post.topic.url
end end
@ -157,7 +139,7 @@ class CustomWizard::Action
else else
log_error( log_error(
"invalid message params", "invalid message params",
"title: #{params[:title]}; post: #{params[:raw]}; recipients: #{params[:target_usernames]}" "title: #{params[:title]}; post: #{params[:raw]}; recipients: #{params[:target_usernames]}",
) )
end end
end end
@ -165,19 +147,14 @@ class CustomWizard::Action
def update_profile def update_profile
params = {} params = {}
if (profile_updates = action['profile_updates']) if (profile_updates = action["profile_updates"])
profile_updates.first[:pairs].each do |pair| profile_updates.first[:pairs].each do |pair|
if allowed_profile_field?(pair['key']) if allowed_profile_field?(pair["key"])
key = cast_profile_key(pair['key']) key = cast_profile_key(pair["key"])
value = cast_profile_value( value =
mapper.map_field( cast_profile_value(mapper.map_field(pair["value"], pair["value_type"]), pair["key"])
pair['value'],
pair['value_type']
),
pair['key']
)
if user_field?(pair['key']) if user_field?(pair["key"])
params[:custom_fields] ||= {} params[:custom_fields] ||= {}
params[:custom_fields][key] = value params[:custom_fields][key] = value
else else
@ -192,12 +169,10 @@ class CustomWizard::Action
if params.present? if params.present?
result = UserUpdater.new(Discourse.system_user, user).update(params) result = UserUpdater.new(Discourse.system_user, user).update(params)
if params[:avatar].present? result = update_avatar(params[:avatar]) if params[:avatar].present?
result = update_avatar(params[:avatar])
end
if result if result
log_success("updated profile fields", "fields: #{params.keys.map(&:to_s).join(',')}") log_success("updated profile fields", "fields: #{params.keys.map(&:to_s).join(",")}")
else else
log_error("failed to update profile fields", "result: #{result.inspect}") log_error("failed to update profile fields", "result: #{result.inspect}")
end end
@ -207,14 +182,10 @@ class CustomWizard::Action
end end
def watch_tags def watch_tags
tags = CustomWizard::Mapper.new( tags = CustomWizard::Mapper.new(inputs: action["tags"], data: mapper_data, user: user).perform
inputs: action['tags'],
data: mapper_data,
user: user
).perform
tags = [*tags] tags = [*tags]
level = action['notification_level'].to_sym level = action["notification_level"].to_sym
if level.blank? if level.blank?
log_error("Notifcation Level was not set. Exiting watch tags action") log_error("Notifcation Level was not set. Exiting watch tags action")
@ -223,23 +194,17 @@ class CustomWizard::Action
users = [] users = []
if action['usernames'] if action["usernames"]
mapped_users = CustomWizard::Mapper.new( mapped_users =
inputs: action['usernames'], CustomWizard::Mapper.new(inputs: action["usernames"], data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
if mapped_users.present? if mapped_users.present?
mapped_users = mapped_users.split(',') mapped_users = mapped_users.split(",").map { |username| User.find_by(username: username) }
.map { |username| User.find_by(username: username) }
users.push(*mapped_users) users.push(*mapped_users)
end end
end end
if ActiveRecord::Type::Boolean.new.cast(action['wizard_user']) users.push(user) if ActiveRecord::Type::Boolean.new.cast(action["wizard_user"])
users.push(user)
end
users.each do |user| users.each do |user|
result = TagUser.batch_set(user, level, tags) result = TagUser.batch_set(user, level, tags)
@ -253,46 +218,38 @@ class CustomWizard::Action
end end
def watch_categories def watch_categories
watched_categories = CustomWizard::Mapper.new( watched_categories =
inputs: action['categories'], CustomWizard::Mapper.new(inputs: action["categories"], data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
watched_categories = [*watched_categories].map(&:to_i) watched_categories = [*watched_categories].map(&:to_i)
notification_level = action['notification_level'] notification_level = action["notification_level"]
if notification_level.blank? if notification_level.blank?
log_error("Notifcation Level was not set. Exiting wizard action") log_error("Notifcation Level was not set. Exiting wizard action")
return return
end end
mute_remainder = CustomWizard::Mapper.new( mute_remainder =
inputs: action['mute_remainder'], CustomWizard::Mapper.new(
data: mapper_data, inputs: action["mute_remainder"],
user: user data: mapper_data,
).perform user: user,
).perform
users = [] users = []
if action['usernames'] if action["usernames"]
mapped_users = CustomWizard::Mapper.new( mapped_users =
inputs: action['usernames'], CustomWizard::Mapper.new(inputs: action["usernames"], data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
if mapped_users.present? if mapped_users.present?
mapped_users = mapped_users.split(',') mapped_users = mapped_users.split(",").map { |username| User.find_by(username: username) }
.map { |username| User.find_by(username: username) }
users.push(*mapped_users) users.push(*mapped_users)
end end
end end
if ActiveRecord::Type::Boolean.new.cast(action['wizard_user']) users.push(user) if ActiveRecord::Type::Boolean.new.cast(action["wizard_user"])
users.push(user)
end
category_ids = Category.all.pluck(:id) category_ids = Category.all.pluck(:id)
set_level = CategoryUser.notification_levels[notification_level.to_sym] set_level = CategoryUser.notification_levels[notification_level.to_sym]
@ -308,37 +265,35 @@ class CustomWizard::Action
new_level = mute_level new_level = mute_level
end end
if new_level CategoryUser.set_notification_level_for_category(user, new_level, category_id) if new_level
CategoryUser.set_notification_level_for_category(user, new_level, category_id)
end
end end
if watched_categories.any? if watched_categories.any?
log_success("#{user.username} notifications for #{watched_categories} set to #{set_level}") log_success("#{user.username} notifications for #{watched_categories} set to #{set_level}")
end end
if mute_remainder log_success("#{user.username} notifications for all other categories muted") if mute_remainder
log_success("#{user.username} notifications for all other categories muted")
end
end end
end end
def send_to_api def send_to_api
api_body = nil api_body = nil
if action['api_body'] != "" if action["api_body"] != ""
begin begin
api_body_parsed = JSON.parse(action['api_body']) api_body_parsed = JSON.parse(action["api_body"])
rescue JSON::ParserError rescue JSON::ParserError
raise Discourse::InvalidParameters, "Invalid API body definition: #{action['api_body']} for #{action['title']}" raise Discourse::InvalidParameters,
"Invalid API body definition: #{action["api_body"]} for #{action["title"]}"
end end
api_body = JSON.parse(mapper.interpolate(JSON.generate(api_body_parsed))) api_body = JSON.parse(mapper.interpolate(JSON.generate(api_body_parsed)))
end end
result = CustomWizard::Api::Endpoint.request(user, action['api'], action['api_endpoint'], api_body) result =
CustomWizard::Api::Endpoint.request(user, action["api"], action["api_endpoint"], api_body)
if error = result['error'] || (result[0] && result[0]['error']) if error = result["error"] || (result[0] && result[0]["error"])
error = error['message'] || error error = error["message"] || error
log_error("api request failed", "message: #{error}") log_error("api request failed", "message: #{error}")
else else
log_success("api request succeeded", "result: #{result}") log_success("api request succeeded", "result: #{result}")
@ -357,7 +312,7 @@ class CustomWizard::Action
end end
if tags = action_tags if tags = action_tags
url += "&tags=#{tags.join(',')}" url += "&tags=#{tags.join(",")}"
end end
route_to = Discourse.base_uri + url route_to = Discourse.base_uri + url
@ -370,14 +325,15 @@ class CustomWizard::Action
end end
def add_to_group def add_to_group
group_map = CustomWizard::Mapper.new( group_map =
inputs: action['group'], CustomWizard::Mapper.new(
data: mapper_data, inputs: action["group"],
user: user, data: mapper_data,
opts: { user: user,
multiple: true opts: {
} multiple: true,
).perform },
).perform
group_map = group_map.flatten.compact group_map = group_map.flatten.compact
@ -386,16 +342,17 @@ class CustomWizard::Action
return return
end end
groups = group_map.reduce([]) do |result, g| groups =
begin group_map.reduce([]) do |result, g|
result.push(Integer(g)) begin
rescue ArgumentError result.push(Integer(g))
group = Group.find_by(name: g) rescue ArgumentError
result.push(group.id) if group group = Group.find_by(name: g)
end result.push(group.id) if group
end
result result
end end
result = nil result = nil
@ -407,29 +364,25 @@ class CustomWizard::Action
end end
if result if result
log_success("added to groups", "groups: #{groups.map(&:to_s).join(',')}") log_success("added to groups", "groups: #{groups.map(&:to_s).join(",")}")
else else
detail = groups.present? ? "groups: #{groups.map(&:to_s).join(',')}" : nil detail = groups.present? ? "groups: #{groups.map(&:to_s).join(",")}" : nil
log_error("failed to add to groups", detail) log_error("failed to add to groups", detail)
end end
end end
def route_to def route_to
return if (url_input = action['url']).blank? return if (url_input = action["url"]).blank?
if url_input.is_a?(String) if url_input.is_a?(String)
url = mapper.interpolate(url_input) url = mapper.interpolate(url_input)
else else
url = CustomWizard::Mapper.new( url = CustomWizard::Mapper.new(inputs: url_input, data: mapper_data, user: user).perform
inputs: url_input,
data: mapper_data,
user: user
).perform
end end
if action['code'].present? if action["code"].present?
@submission.fields[action['code']] = SecureRandom.hex(8) @submission.fields[action["code"]] = SecureRandom.hex(8)
url += "&#{action['code']}=#{@submission.fields[action['code']]}" url += "&#{action["code"]}=#{@submission.fields[action["code"]]}"
end end
route_to = UrlHelper.encode(url) route_to = UrlHelper.encode(url)
@ -465,9 +418,7 @@ class CustomWizard::Action
user_ids.each { |user_id| group.group_users.build(user_id: user_id) } user_ids.each { |user_id| group.group_users.build(user_id: user_id) }
end end
if group.save log_success("Group created", group.name) if group.save
log_success("Group created", group.name)
end
result.output = group.name result.output = group.name
else else
@ -504,11 +455,8 @@ class CustomWizard::Action
private private
def action_category def action_category
output = CustomWizard::Mapper.new( output =
inputs: action['category'], CustomWizard::Mapper.new(inputs: action["category"], data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
return false if output.blank? return false if output.blank?
@ -522,32 +470,26 @@ class CustomWizard::Action
end end
def action_tags def action_tags
output = CustomWizard::Mapper.new( output = CustomWizard::Mapper.new(inputs: action["tags"], data: mapper_data, user: user).perform
inputs: action['tags'],
data: mapper_data,
user: user,
).perform
return false if output.blank? return false if output.blank?
if output.is_a?(Array) if output.is_a?(Array)
output.flatten output.flatten
else output.is_a?(String) else
output.is_a?(String)
[*output] [*output]
end end
end end
def add_custom_fields(params = {}) def add_custom_fields(params = {})
if (custom_fields = action['custom_fields']).present? if (custom_fields = action["custom_fields"]).present?
field_map = CustomWizard::Mapper.new( field_map =
inputs: custom_fields, CustomWizard::Mapper.new(inputs: custom_fields, data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
registered_fields = CustomWizard::CustomField.full_list registered_fields = CustomWizard::CustomField.full_list
field_map.each do |field| field_map.each do |field|
keyArr = field[:key].split('.') keyArr = field[:key].split(".")
value = field[:value] value = field[:value]
if keyArr.length > 1 if keyArr.length > 1
@ -601,28 +543,32 @@ class CustomWizard::Action
skip_validations: true, skip_validations: true,
topic_opts: { topic_opts: {
custom_fields: { custom_fields: {
wizard_submission_id: @wizard.current_submission.id wizard_submission_id: @wizard.current_submission.id,
} },
} },
} }
params[:title] = CustomWizard::Mapper.new( params[:title] = CustomWizard::Mapper.new(
inputs: action['title'], inputs: action["title"],
data: mapper_data, data: mapper_data,
user: user user: user,
).perform ).perform
params[:raw] = action['post_builder'] ? params[:raw] = (
mapper.interpolate( if action["post_builder"]
action['post_template'], mapper.interpolate(
user: true, action["post_template"],
value: true, user: true,
wizard: true, value: true,
template: true wizard: true,
) : template: true,
@submission.fields[action['post']] )
else
@submission.fields[action["post"]]
end
)
params[:import_mode] = ActiveRecord::Type::Boolean.new.cast(action['suppress_notifications']) params[:import_mode] = ActiveRecord::Type::Boolean.new.cast(action["suppress_notifications"])
add_custom_fields(params) add_custom_fields(params)
end end
@ -644,7 +590,7 @@ class CustomWizard::Action
params[field.to_sym] = CustomWizard::Mapper.new( params[field.to_sym] = CustomWizard::Mapper.new(
inputs: action[field], inputs: action[field],
data: mapper_data, data: mapper_data,
user: user user: user,
).perform ).perform
end end
end end
@ -654,52 +600,48 @@ class CustomWizard::Action
end end
def topic_poster def topic_poster
@topic_poster ||= begin @topic_poster ||=
poster_id = CustomWizard::Mapper.new( begin
inputs: action['poster'], poster_id =
data: mapper_data, CustomWizard::Mapper.new(inputs: action["poster"], data: mapper_data, user: user).perform
user: user, poster_id = [*poster_id].first if poster_id.present?
).perform
poster_id = [*poster_id].first if poster_id.present?
if poster_id.blank? || poster_id === WIZARD_USER if poster_id.blank? || poster_id === WIZARD_USER
poster = user || guest_user poster = user || guest_user
else else
poster = User.find_by_username(poster_id) poster = User.find_by_username(poster_id)
end
poster || Discourse.system_user
end end
poster || Discourse.system_user
end
end end
def guest_user def guest_user
@guest_user ||= begin @guest_user ||=
return nil unless action['guest_email'] begin
return nil unless action["guest_email"]
email = CustomWizard::Mapper.new( email = CustomWizard::Mapper.new(inputs: action["guest_email"], data: mapper_data).perform
inputs: action['guest_email'],
data: mapper_data,
).perform
if email&.match(/@/) if email&.match(/@/)
if user = User.find_by_email(email) if user = User.find_by_email(email)
user user
else else
User.create!( User.create!(
email: email, email: email,
username: UserNameSuggester.suggest(email), username: UserNameSuggester.suggest(email),
name: User.suggest_name(email), name: User.suggest_name(email),
staged: true, staged: true,
) )
end
end end
end end
end
end end
def new_group_params def new_group_params
params = {} params = {}
%w( %w[
name name
full_name full_name
title title
@ -711,26 +653,18 @@ class CustomWizard::Action
visibility_level visibility_level
members_visibility_level members_visibility_level
grant_trust_level grant_trust_level
).each do |attr| ].each do |attr|
input = action[attr] input = action[attr]
if attr === "name" && input.blank? raise ArgumentError.new if attr === "name" && input.blank?
raise ArgumentError.new
end
if attr === "full_name" && input.blank? input = action["name"] if attr === "full_name" && input.blank?
input = action["name"]
end
if input.present? if input.present?
value = CustomWizard::Mapper.new( value = CustomWizard::Mapper.new(inputs: input, data: mapper_data, user: user).perform
inputs: input,
data: mapper_data,
user: user
).perform
if value if value
value = value.parameterize(separator: '_') if attr === "name" value = value.parameterize(separator: "_") if attr === "name"
value = value.to_i if attr.include?("_level") value = value.to_i if attr.include?("_level")
params[attr.to_sym] = value params[attr.to_sym] = value
@ -744,25 +678,13 @@ class CustomWizard::Action
def new_category_params def new_category_params
params = {} params = {}
%w( %w[name slug color text_color parent_category_id permissions].each do |attr|
name
slug
color
text_color
parent_category_id
permissions
).each do |attr|
if action[attr].present? if action[attr].present?
value = CustomWizard::Mapper.new( value =
inputs: action[attr], CustomWizard::Mapper.new(inputs: action[attr], data: mapper_data, user: user).perform
data: mapper_data,
user: user
).perform
if value if value
if attr === "parent_category_id" && value.is_a?(Array) value = value[0] if attr === "parent_category_id" && value.is_a?(Array)
value = value[0]
end
if attr === "permissions" && value.is_a?(Array) if attr === "permissions" && value.is_a?(Array)
permissions = value permissions = value
@ -776,16 +698,14 @@ class CustomWizard::Action
group = Group.find_by(id: k[0]) group = Group.find_by(id: k[0])
k = group.name k = group.name
else else
k = k.parameterize(separator: '_') k = k.parameterize(separator: "_")
end end
value[k] = v value[k] = v
end end
end end
if attr === 'slug' value = value.parameterize(separator: "-") if attr === "slug"
value = value.parameterize(separator: '-')
end
params[attr.to_sym] = value params[attr.to_sym] = value
end end
@ -796,15 +716,15 @@ class CustomWizard::Action
end end
def creates_post? def creates_post?
[:create_topic, :send_message].include?(action['type'].to_sym) %i[create_topic send_message].include?(action["type"].to_sym)
end end
def public_topic_fields def public_topic_fields
['visible'] ["visible"]
end end
def profile_url_fields def profile_url_fields
['profile_background', 'card_background'] %w[profile_background card_background]
end end
def cast_profile_key(key) def cast_profile_key(key)
@ -819,16 +739,16 @@ class CustomWizard::Action
return value if value.nil? return value if value.nil?
if profile_url_fields.include?(key) if profile_url_fields.include?(key)
value['url'] value["url"]
elsif key === 'avatar' elsif key === "avatar"
value['id'] value["id"]
else else
value value
end end
end end
def profile_excluded_fields def profile_excluded_fields
['username', 'email', 'trust_level'].freeze %w[username email trust_level].freeze
end end
def allowed_profile_field?(field) def allowed_profile_field?(field)
@ -837,13 +757,12 @@ class CustomWizard::Action
def user_field?(field) def user_field?(field)
field.to_s.include?(::User::USER_FIELD_PREFIX) && field.to_s.include?(::User::USER_FIELD_PREFIX) &&
::UserField.exists?(field.split('_').last.to_i) ::UserField.exists?(field.split("_").last.to_i)
end end
def allowed_profile_fields def allowed_profile_fields
CustomWizard::Mapper.user_fields.select { |f| profile_excluded_fields.exclude?(f) } + CustomWizard::Mapper.user_fields.select { |f| profile_excluded_fields.exclude?(f) } +
profile_url_fields + profile_url_fields + ["avatar"]
['avatar']
end end
def update_avatar(upload_id) def update_avatar(upload_id)
@ -875,11 +794,6 @@ class CustomWizard::Action
def save_log def save_log
username = user ? user.username : @wizard.actor_id username = user ? user.username : @wizard.actor_id
CustomWizard::Log.create( CustomWizard::Log.create(@wizard.id, action["type"], username, @log.join("; "))
@wizard.id,
action['type'],
username,
@log.join('; ')
)
end end
end end

Datei anzeigen

@ -2,14 +2,11 @@
class CustomWizard::Api class CustomWizard::Api
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
attr_accessor :name, attr_accessor :name, :title
:title
def initialize(name, data = {}) def initialize(name, data = {})
@name = name @name = name
data.each do |k, v| data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
self.send "#{k}=", v if self.respond_to?(k)
end
end end
def self.set(name, data) def self.set(name, data)
@ -27,9 +24,10 @@ class CustomWizard::Api
end end
def self.list def self.list
PluginStoreRow.where("plugin_name LIKE 'custom_wizard_api_%' AND key = 'metadata'") PluginStoreRow
.where("plugin_name LIKE 'custom_wizard_api_%' AND key = 'metadata'")
.map do |record| .map do |record|
self.new(record['plugin_name'].sub("custom_wizard_api_", ""), ::JSON.parse(record['value'])) self.new(record["plugin_name"].sub("custom_wizard_api_", ""), ::JSON.parse(record["value"]))
end end
end end
end end

Datei anzeigen

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'excon' require "excon"
class CustomWizard::Api::Authorization class CustomWizard::Api::Authorization
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
@ -23,9 +23,7 @@ class CustomWizard::Api::Authorization
def initialize(api_name, data = {}) def initialize(api_name, data = {})
@api_name = api_name @api_name = api_name
data.each do |k, v| data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
self.send "#{k}=", v if self.respond_to?(k)
end
end end
def authorized def authorized
@ -33,16 +31,13 @@ class CustomWizard::Api::Authorization
end end
def self.set(api_name, new_data = {}) def self.set(api_name, new_data = {})
api_name = api_name.underscore api_name = api_name.underscore
data = self.get(api_name, data_only: true) || {} data = self.get(api_name, data_only: true) || {}
new_data.each do |k, v| new_data.each { |k, v| data[k.to_sym] = v }
data[k.to_sym] = v
end
PluginStore.set("custom_wizard_api_#{api_name}", 'authorization', data) PluginStore.set("custom_wizard_api_#{api_name}", "authorization", data)
self.get(api_name) self.get(api_name)
end end
@ -50,7 +45,7 @@ class CustomWizard::Api::Authorization
def self.get(api_name, opts = {}) def self.get(api_name, opts = {})
api_name = api_name.underscore api_name = api_name.underscore
if data = PluginStore.get("custom_wizard_api_#{api_name}", 'authorization') if data = PluginStore.get("custom_wizard_api_#{api_name}", "authorization")
if opts[:data_only] if opts[:data_only]
data data
else else
@ -67,14 +62,14 @@ class CustomWizard::Api::Authorization
def self.authorization_string(name) def self.authorization_string(name)
auth = CustomWizard::Api::Authorization.get(name) auth = CustomWizard::Api::Authorization.get(name)
raise Discourse::InvalidParameters.new(:name) unless auth.present? raise Discourse::InvalidParameters.new(:name) if auth.blank?
if auth.auth_type === "basic" if auth.auth_type === "basic"
raise Discourse::InvalidParameters.new(:username) unless auth.username.present? raise Discourse::InvalidParameters.new(:username) if auth.username.blank?
raise Discourse::InvalidParameters.new(:password) unless auth.password.present? raise Discourse::InvalidParameters.new(:password) if auth.password.blank?
"Basic #{Base64.strict_encode64((auth.username + ":" + auth.password).chomp)}" "Basic #{Base64.strict_encode64((auth.username + ":" + auth.password).chomp)}"
elsif ['oauth_3', 'oauth_2'].include?(auth.auth_type) elsif %w[oauth_3 oauth_2].include?(auth.auth_type)
raise Discourse::InvalidParameters.new(auth.access_token) unless auth.access_token.present? raise Discourse::InvalidParameters.new(auth.access_token) if auth.access_token.blank?
"Bearer #{auth.access_token}" "Bearer #{auth.access_token}"
else else
nil nil
@ -87,38 +82,51 @@ class CustomWizard::Api::Authorization
body = {} body = {}
if opts[:refresh] && type === 'oauth_3' if opts[:refresh] && type === "oauth_3"
body['grant_type'] = 'refresh_token' body["grant_type"] = "refresh_token"
elsif type === 'oauth_2' elsif type === "oauth_2"
body['grant_type'] = 'client_credentials' body["grant_type"] = "client_credentials"
elsif type === 'oauth_3' elsif type === "oauth_3"
body['grant_type'] = 'authorization_code' body["grant_type"] = "authorization_code"
end end
unless opts[:refresh] unless opts[:refresh]
body['client_id'] = authorization.client_id body["client_id"] = authorization.client_id
body['client_secret'] = authorization.client_secret body["client_secret"] = authorization.client_secret
end end
if type === 'oauth_3' if type === "oauth_3"
body['code'] = authorization.code body["code"] = authorization.code
body['redirect_uri'] = Discourse.base_url + "/admin/wizards/apis/#{name}/redirect" body["redirect_uri"] = Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
end end
connection = Excon.new( connection =
authorization.token_url, Excon.new(
headers: { authorization.token_url,
"Content-Type" => "application/x-www-form-urlencoded" headers: {
}, "Content-Type" => "application/x-www-form-urlencoded",
method: 'GET', },
query: URI.encode_www_form(body) method: "GET",
) query: URI.encode_www_form(body),
)
begin begin
result = connection.request() result = connection.request()
log_params = { time: Time.now, user_id: 0, status: 'SUCCESS', url: authorization.token_url, error: "" } log_params = {
time: Time.now,
user_id: 0,
status: "SUCCESS",
url: authorization.token_url,
error: "",
}
CustomWizard::Api::LogEntry.set(name, log_params) CustomWizard::Api::LogEntry.set(name, log_params)
rescue SystemCallError => e rescue SystemCallError => e
log_params = { time: Time.now, user_id: 0, status: 'FAILURE', url: authorization.token_url, error: "Token refresh request failed: #{e.inspect}" } log_params = {
time: Time.now,
user_id: 0,
status: "FAILURE",
url: authorization.token_url,
error: "Token refresh request failed: #{e.inspect}",
}
CustomWizard::Api::LogEntry.set(name, log_params) CustomWizard::Api::LogEntry.set(name, log_params)
end end
@ -128,25 +136,21 @@ class CustomWizard::Api::Authorization
def self.handle_token_result(name, result) def self.handle_token_result(name, result)
result_data = JSON.parse(result.body) result_data = JSON.parse(result.body)
if result_data['error'] return result_data if result_data["error"]
return result_data
end
data = {} data = {}
data['access_token'] = result_data['access_token'] data["access_token"] = result_data["access_token"]
data['refresh_token'] = result_data['refresh_token'] if result_data['refresh_token'] data["refresh_token"] = result_data["refresh_token"] if result_data["refresh_token"]
data['token_type'] = result_data['token_type'] if result_data['token_type'] data["token_type"] = result_data["token_type"] if result_data["token_type"]
if result_data['expires_in'] if result_data["expires_in"]
data['token_expires_at'] = Time.now + result_data['expires_in'].seconds data["token_expires_at"] = Time.now + result_data["expires_in"].seconds
data['token_refresh_at'] = data['token_expires_at'].to_time - 10.minutes data["token_refresh_at"] = data["token_expires_at"].to_time - 10.minutes
opts = { opts = { name: name }
name: name
}
Jobs.enqueue_at(data['token_refresh_at'], :refresh_api_access_token, opts) Jobs.enqueue_at(data["token_refresh_at"], :refresh_api_access_token, opts)
end end
CustomWizard::Api::Authorization.set(name, data) CustomWizard::Api::Authorization.set(name, data)

Datei anzeigen

@ -2,34 +2,24 @@
class CustomWizard::Api::Endpoint class CustomWizard::Api::Endpoint
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
attr_accessor :id, attr_accessor :id, :name, :api_name, :method, :url, :content_type, :success_codes
:name,
:api_name,
:method,
:url,
:content_type,
:success_codes
def initialize(api_name, data = {}) def initialize(api_name, data = {})
@api_name = api_name @api_name = api_name
data.each do |k, v| data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
self.send "#{k}=", v if self.respond_to?(k)
end
end end
def self.set(api_name, new_data) def self.set(api_name, new_data)
if new_data['id'] if new_data["id"]
data = self.get(api_name, new_data['id'], data_only: true) data = self.get(api_name, new_data["id"], data_only: true)
endpoint_id = new_data['id'] endpoint_id = new_data["id"]
else else
data = {} data = {}
endpoint_id = SecureRandom.hex(3) endpoint_id = SecureRandom.hex(3)
end end
new_data.each do |k, v| new_data.each { |k, v| data[k.to_sym] = v }
data[k.to_sym] = v
end
PluginStore.set("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}", data) PluginStore.set("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}", data)
@ -52,15 +42,18 @@ class CustomWizard::Api::Endpoint
end end
def self.remove(api_name) def self.remove(api_name)
PluginStoreRow.where("plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'endpoint_%'").destroy_all PluginStoreRow.where(
"plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'endpoint_%'",
).destroy_all
end end
def self.list(api_name) def self.list(api_name)
PluginStoreRow.where("plugin_name LIKE 'custom_wizard_api_#{api_name}' AND key LIKE 'endpoint_%'") PluginStoreRow
.where("plugin_name LIKE 'custom_wizard_api_#{api_name}' AND key LIKE 'endpoint_%'")
.map do |record| .map do |record|
api_name = record['plugin_name'].sub("custom_wizard_api_", "") api_name = record["plugin_name"].sub("custom_wizard_api_", "")
data = ::JSON.parse(record['value']) data = ::JSON.parse(record["value"])
data[:id] = record['key'].split('_').last data[:id] = record["key"].split("_").last
self.new(api_name, data) self.new(api_name, data)
end end
end end
@ -97,12 +90,12 @@ class CustomWizard::Api::Endpoint
result = response.body result = response.body
end end
CustomWizard::Api::LogEntry.set(api_name, log_params(user, 'SUCCESS', endpoint.url)) CustomWizard::Api::LogEntry.set(api_name, log_params(user, "SUCCESS", endpoint.url))
result result
else else
message = "API request failed" message = "API request failed"
CustomWizard::Api::LogEntry.set(api_name, log_params(user, 'FAIL', endpoint.url, message)) CustomWizard::Api::LogEntry.set(api_name, log_params(user, "FAIL", endpoint.url, message))
{ error: message } { error: message }
end end
end end

Datei anzeigen

@ -16,23 +16,19 @@ class CustomWizard::Api::LogEntry
def initialize(api_name, data = {}) def initialize(api_name, data = {})
@api_name = api_name @api_name = api_name
data.each do |k, v| data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
self.send "#{k}=", v if self.respond_to?(k)
end
end end
def self.set(api_name, new_data) def self.set(api_name, new_data)
if new_data['log_id'] if new_data["log_id"]
data = self.get(api_name, new_data['log_id'], data_only: true) data = self.get(api_name, new_data["log_id"], data_only: true)
log_id = new_data['log_id'] log_id = new_data["log_id"]
else else
data = {} data = {}
log_id = SecureRandom.hex(8) log_id = SecureRandom.hex(8)
end end
new_data.each do |k, v| new_data.each { |k, v| data[k.to_sym] = v }
data[k.to_sym] = v
end
PluginStore.set("custom_wizard_api_#{api_name}", "log_#{log_id}", data) PluginStore.set("custom_wizard_api_#{api_name}", "log_#{log_id}", data)
@ -55,16 +51,19 @@ class CustomWizard::Api::LogEntry
end end
def self.remove(api_name) def self.remove(api_name)
PluginStoreRow.where("plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'log_%'").destroy_all PluginStoreRow.where(
"plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'log_%'",
).destroy_all
end end
def self.list(api_name) def self.list(api_name)
PluginStoreRow.where("plugin_name LIKE 'custom_wizard_api_#{api_name}' AND key LIKE 'log_%'") PluginStoreRow
.where("plugin_name LIKE 'custom_wizard_api_#{api_name}' AND key LIKE 'log_%'")
.map do |record| .map do |record|
api_name = record['plugin_name'].sub("custom_wizard_api_", "") api_name = record["plugin_name"].sub("custom_wizard_api_", "")
data = ::JSON.parse(record['value']) data = ::JSON.parse(record["value"])
data[:log_id] = record['key'].split('_').last data[:log_id] = record["key"].split("_").last
this_user = User.find_by(id: data['user_id']) this_user = User.find_by(id: data["user_id"])
if this_user.nil? if this_user.nil?
data[:user_id] = nil data[:user_id] = nil
data[:username] = "" data[:username] = ""
@ -76,14 +75,17 @@ class CustomWizard::Api::LogEntry
data[:username] = this_user.username || "" data[:username] = this_user.username || ""
data[:userpath] = "/u/#{this_user.username_lower}/activity" data[:userpath] = "/u/#{this_user.username_lower}/activity"
data[:name] = this_user.name || "" data[:name] = this_user.name || ""
data[:avatar_template] = "/user_avatar/default/#{this_user.username_lower}/97/#{this_user.uploaded_avatar_id}.png" data[
:avatar_template
] = "/user_avatar/default/#{this_user.username_lower}/97/#{this_user.uploaded_avatar_id}.png"
end end
self.new(api_name, data) self.new(api_name, data)
end end
end end
def self.clear(api_name) def self.clear(api_name)
PluginStoreRow.where("plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'log_%'").destroy_all PluginStoreRow.where(
"plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'log_%'",
).destroy_all
end end
end end

Datei anzeigen

@ -30,7 +30,7 @@ class CustomWizard::Builder
@template.steps.each do |step_template| @template.steps.each do |step_template|
next if !check_condition(step_template) next if !check_condition(step_template)
@wizard.append_step(step_template['id']) do |step| @wizard.append_step(step_template["id"]) do |step|
step = check_if_permitted(step, step_template) step = check_if_permitted(step, step_template)
next if !step.permitted next if !step.permitted
@ -73,15 +73,16 @@ class CustomWizard::Builder
end end
def check_condition(template) def check_condition(template)
if template['condition'].present? if template["condition"].present?
result = CustomWizard::Mapper.new( result =
inputs: template['condition'], CustomWizard::Mapper.new(
user: @wizard.user, inputs: template["condition"],
data: @wizard.current_submission&.fields_and_meta, user: @wizard.user,
opts: { data: @wizard.current_submission&.fields_and_meta,
multiple: true opts: {
} multiple: true,
).perform },
).perform
result.any? result.any?
else else
@ -92,126 +93,121 @@ class CustomWizard::Builder
private private
def mapper def mapper
CustomWizard::Mapper.new( CustomWizard::Mapper.new(user: @wizard.user, data: @wizard.current_submission&.fields_and_meta)
user: @wizard.user,
data: @wizard.current_submission&.fields_and_meta
)
end end
def append_field(step, step_template, field_template, build_opts) def append_field(step, step_template, field_template, build_opts)
params = { params = {
id: field_template['id'], id: field_template["id"],
type: field_template['type'], type: field_template["type"],
required: field_template['required'] required: field_template["required"],
} }
%w(label description image key validations min_length max_length char_counter tag_groups).each do |key| %w[
params[key.to_sym] = field_template[key] if field_template[key] label
end description
image
key
validations
min_length
max_length
char_counter
tag_groups
].each { |key| params[key.to_sym] = field_template[key] if field_template[key] }
params[:value] = prefill_field(field_template, step_template) params[:value] = prefill_field(field_template, step_template)
if !build_opts[:reset] && (submission = @wizard.current_submission).present? 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
if field_template['type'] === 'group' && params[:value].present? if field_template["type"] === "group" && params[:value].present?
params[:value] = params[:value].first params[:value] = params[:value].first
end end
if field_template['type'] === 'checkbox' params[:value] = standardise_boolean(params[:value]) if field_template["type"] === "checkbox"
params[:value] = standardise_boolean(params[:value])
params[:file_types] = field_template["file_types"] if field_template["type"] === "upload"
if %w[date time date_time].include?(field_template["type"])
params[:format] = field_template["format"]
end end
if field_template['type'] === 'upload' if %w[category tag topic].include?(field_template["type"])
params[:file_types] = field_template['file_types'] params[:limit] = field_template["limit"]
end end
if ['date', 'time', 'date_time'].include?(field_template['type']) if field_template["type"] === "tag"
params[:format] = field_template['format'] params[:can_create_tag] = standardise_boolean(field_template["can_create_tag"])
end end
if %w[category tag topic].include?(field_template['type']) params[:property] = field_template["property"] if field_template["type"] === "category"
params[:limit] = field_template['limit']
end
if field_template['type'] === 'tag' params[:category] = field_template["category"] if field_template["type"] === "topic"
params[:can_create_tag] = standardise_boolean(field_template['can_create_tag'])
end
if field_template['type'] === 'category' if (content_inputs = field_template["content"]).present?
params[:property] = field_template['property'] content =
end CustomWizard::Mapper.new(
inputs: content_inputs,
user: @wizard.user,
data: @wizard.current_submission&.fields_and_meta,
opts: {
with_type: true,
},
).perform
if field_template['type'] === 'topic' if content.present? && content[:result].present?
params[:category] = field_template['category'] if content[:type] == "association"
end content[:result] = content[:result].map { |item| { id: item[:key], name: item[:value] } }
if (content_inputs = field_template['content']).present?
content = CustomWizard::Mapper.new(
inputs: content_inputs,
user: @wizard.user,
data: @wizard.current_submission&.fields_and_meta,
opts: {
with_type: true
}
).perform
if content.present? &&
content[:result].present?
if content[:type] == 'association'
content[:result] = content[:result].map do |item|
{
id: item[:key],
name: item[:value]
}
end
end end
params[:content] = content[:result] params[:content] = content[:result]
end end
end end
if field_template['index'].present? if field_template["index"].present?
index = CustomWizard::Mapper.new( index =
inputs: field_template['index'], CustomWizard::Mapper.new(
user: @wizard.user, inputs: field_template["index"],
data: @wizard.current_submission&.fields_and_meta user: @wizard.user,
).perform data: @wizard.current_submission&.fields_and_meta,
).perform
params[:index] = index.to_i unless index.nil? params[:index] = index.to_i unless index.nil?
end end
if field_template['description'].present? if field_template["description"].present?
params[:description] = mapper.interpolate( params[:description] = mapper.interpolate(
field_template['description'], field_template["description"],
user: @wizard.user, user: @wizard.user,
value: true, value: true,
wizard: true, wizard: true,
template: true template: true,
) )
end end
if field_template['preview_template'].present? if field_template["preview_template"].present?
preview_template = mapper.interpolate( preview_template =
field_template['preview_template'], mapper.interpolate(
user: @wizard.user, field_template["preview_template"],
value: true, user: @wizard.user,
wizard: true, value: true,
template: true wizard: true,
) template: true,
)
params[:preview_template] = PrettyText.cook(preview_template) params[:preview_template] = PrettyText.cook(preview_template)
end end
if field_template['placeholder'].present? if field_template["placeholder"].present?
params[:placeholder] = mapper.interpolate( params[:placeholder] = mapper.interpolate(
field_template['placeholder'], field_template["placeholder"],
user: @wizard.user, user: @wizard.user,
value: true, value: true,
wizard: true, wizard: true,
template: true template: true,
) )
end end
@ -219,11 +215,11 @@ class CustomWizard::Builder
end end
def prefill_field(field_template, step_template) def prefill_field(field_template, step_template)
if (prefill = field_template['prefill']).present? if (prefill = field_template["prefill"]).present?
CustomWizard::Mapper.new( CustomWizard::Mapper.new(
inputs: prefill, inputs: prefill,
user: @wizard.user, user: @wizard.user,
data: @wizard.current_submission&.fields_and_meta data: @wizard.current_submission&.fields_and_meta,
).perform ).perform
end end
end end
@ -231,13 +227,11 @@ class CustomWizard::Builder
def check_if_permitted(step, step_template) def check_if_permitted(step, step_template)
step.permitted = true step.permitted = true
if step_template['required_data'] step = ensure_required_data(step, step_template) if step_template["required_data"]
step = ensure_required_data(step, step_template)
end
if !step.permitted if !step.permitted
if step_template['required_data_message'] if step_template["required_data_message"]
step.permitted_message = step_template['required_data_message'] step.permitted_message = step_template["required_data_message"]
end end
end end
@ -245,18 +239,19 @@ class CustomWizard::Builder
end end
def add_step_attributes(step, step_template) def add_step_attributes(step, step_template)
%w(index title banner key force_final).each do |attr| %w[index title banner key force_final].each do |attr|
step.send("#{attr}=", step_template[attr]) if step_template[attr] step.send("#{attr}=", step_template[attr]) if step_template[attr]
end end
if step_template['description'] if step_template["description"]
step.description = mapper.interpolate( step.description =
step_template['description'], mapper.interpolate(
user: @wizard.user, step_template["description"],
value: true, user: @wizard.user,
wizard: true, value: true,
template: true wizard: true,
) template: true,
)
step.description = PrettyText.cook(step.description) step.description = PrettyText.cook(step.description)
end end
@ -264,8 +259,8 @@ class CustomWizard::Builder
end end
def append_step_fields(step, step_template, build_opts) def append_step_fields(step, step_template, build_opts)
if step_template['fields'] && step_template['fields'].length if step_template["fields"] && step_template["fields"].length
step_template['fields'].each do |field_template| step_template["fields"].each do |field_template|
next if !check_condition(field_template) next if !check_condition(field_template)
append_field(step, step_template, field_template, build_opts) append_field(step, step_template, field_template, build_opts)
end end
@ -280,18 +275,18 @@ class CustomWizard::Builder
end end
def save_permitted_params(step_template, params) def save_permitted_params(step_template, params)
return unless step_template['permitted_params'].present? return if step_template["permitted_params"].blank?
permitted_params = step_template['permitted_params'] permitted_params = step_template["permitted_params"]
permitted_data = {} permitted_data = {}
submission_key = nil submission_key = nil
params_key = nil params_key = nil
submission = @wizard.current_submission 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 && params[params_key].present? if submission_key && params_key && params[params_key].present?
submission.permitted_param_keys << submission_key.to_s submission.permitted_param_keys << submission_key.to_s
@ -303,19 +298,15 @@ class CustomWizard::Builder
end end
def ensure_required_data(step, step_template) def ensure_required_data(step, step_template)
step_template['required_data'].each do |required| step_template["required_data"].each do |required|
pairs = required['pairs'].select do |pair| pairs = required["pairs"].select { |pair| pair["key"].present? && pair["value"].present? }
pair['key'].present? && pair['value'].present?
end
if pairs.any? && !@wizard.current_submission.present? if pairs.any? && !@wizard.current_submission.present?
step.permitted = false step.permitted = false
break break
end end
pairs.each do |pair| pairs.each { |pair| pair["key"] = @wizard.current_submission.fields[pair["key"]] }
pair['key'] = @wizard.current_submission.fields[pair['key']]
end
if !mapper.validate_pairs(pairs) if !mapper.validate_pairs(pairs)
step.permitted = false step.permitted = false
@ -328,25 +319,22 @@ class CustomWizard::Builder
def apply_step_handlers def apply_step_handlers
CustomWizard::Builder.step_handlers.each do |handler| CustomWizard::Builder.step_handlers.each do |handler|
if handler[:wizard_id] == @wizard.id handler[:block].call(self) if handler[:wizard_id] == @wizard.id
handler[:block].call(self)
end
end end
end end
def run_step_actions def run_step_actions
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
result = CustomWizard::Action.new( result =
action: action_template, CustomWizard::Action.new(
wizard: @wizard, action: action_template,
submission: @submission wizard: @wizard,
).perform submission: @submission,
).perform
if result.success? @submission = result.submission if result.success?
@submission = result.submission
end
end end
end end
end end

Datei anzeigen

@ -6,20 +6,20 @@ class ::CustomWizard::CustomField
attr_reader :id attr_reader :id
ATTRS ||= ["name", "klass", "type", "serializers"] ATTRS ||= %w[name klass type serializers]
REQUIRED ||= ["name", "klass", "type"] REQUIRED ||= %w[name klass type]
NAMESPACE ||= "custom_wizard_custom_fields" NAMESPACE ||= "custom_wizard_custom_fields"
NAME_MIN_LENGTH ||= 3 NAME_MIN_LENGTH ||= 3
CLASSES ||= { CLASSES ||= {
topic: ["topic_view", "topic_list_item"], topic: %w[topic_view topic_list_item],
group: ["basic_group"], group: ["basic_group"],
category: ["basic_category"], category: ["basic_category"],
post: ["post"] post: ["post"],
} }
TYPES ||= ["string", "boolean", "integer", "json"] TYPES ||= %w[string boolean integer json]
LIST_CACHE_KEY ||= 'custom_field_list' LIST_CACHE_KEY ||= "custom_field_list"
def self.serializers def self.serializers
CLASSES.values.flatten.uniq CLASSES.values.flatten.uniq
@ -34,9 +34,7 @@ class ::CustomWizard::CustomField
value = data[attr] value = data[attr]
if value.present? send("#{attr}=", value) if value.present?
send("#{attr}=", value)
end
end end
@subscription = CustomWizard::Subscription.new @subscription = CustomWizard::Subscription.new
@ -49,9 +47,7 @@ class ::CustomWizard::CustomField
data = {} data = {}
key = name key = name
(ATTRS - ['name']).each do |attr| (ATTRS - ["name"]).each { |attr| data[attr] = send(attr) }
data[attr] = send(attr)
end
if self.class.save_to_store(id, key, data) if self.class.save_to_store(id, key, data)
self.class.invalidate_cache self.class.invalidate_cache
@ -74,39 +70,38 @@ class ::CustomWizard::CustomField
break break
end end
if attr == 'serializers' && !value.is_a?(Array) next if attr == "serializers" && !value.is_a?(Array)
next
end
if (attr == 'klass' && CLASSES.keys.exclude?(value.to_sym)) || if (attr == "klass" && CLASSES.keys.exclude?(value.to_sym)) ||
(attr == 'serializers' && CLASSES[klass.to_sym].blank?) (attr == "serializers" && CLASSES[klass.to_sym].blank?)
add_error(I18n.t("#{i18n_key}.unsupported_class", class: value)) add_error(I18n.t("#{i18n_key}.unsupported_class", class: value))
next next
end end
if attr == 'klass' && !@subscription.includes?(:custom_field, :klass, value) if attr == "klass" && !@subscription.includes?(:custom_field, :klass, value)
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value)) add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
end end
if attr == 'serializers' && (unsupported = value - CLASSES[klass.to_sym]).length > 0 if attr == "serializers" && (unsupported = value - CLASSES[klass.to_sym]).length > 0
add_error(I18n.t("#{i18n_key}.unsupported_serializers", add_error(
class: klass, I18n.t(
serializers: unsupported.join(", ") "#{i18n_key}.unsupported_serializers",
)) class: klass,
serializers: unsupported.join(", "),
),
)
end end
if attr == 'type' && TYPES.exclude?(value) if attr == "type" && TYPES.exclude?(value)
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value)) add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
end end
if attr == 'type' && !@subscription.includes?(:custom_field, :type, value) if attr == "type" && !@subscription.includes?(:custom_field, :type, value)
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value)) add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
end end
if attr == 'name' if attr == "name"
unless value.is_a?(String) add_error(I18n.t("#{i18n_key}.name_invalid", name: value)) unless value.is_a?(String)
add_error(I18n.t("#{i18n_key}.name_invalid", name: value))
end
if value.length < NAME_MIN_LENGTH if value.length < NAME_MIN_LENGTH
add_error(I18n.t("#{i18n_key}.name_too_short", name: value, min_length: NAME_MIN_LENGTH)) add_error(I18n.t("#{i18n_key}.name_too_short", name: value, min_length: NAME_MIN_LENGTH))
@ -117,8 +112,8 @@ class ::CustomWizard::CustomField
end end
begin begin
@name = value.parameterize(separator: '_') @name = value.parameterize(separator: "_")
rescue rescue StandardError
add_error(I18n.t("#{i18n_key}.name_invalid", name: value)) add_error(I18n.t("#{i18n_key}.name_invalid", name: value))
end end
end end
@ -134,17 +129,16 @@ class ::CustomWizard::CustomField
end end
def self.list def self.list
PluginStoreRow.where(plugin_name: NAMESPACE).map do |record| PluginStoreRow.where(plugin_name: NAMESPACE).map { |record| create_from_store(record) }
create_from_store(record)
end
end end
def self.cached_list def self.cached_list
@custom_wizard_cached_fields ||= ::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do @custom_wizard_cached_fields ||=
PluginStoreRow.where(plugin_name: NAMESPACE).map do |record| ::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do
create_from_store(record).as_json.with_indifferent_access PluginStoreRow
.where(plugin_name: NAMESPACE)
.map { |record| create_from_store(record).as_json.with_indifferent_access }
end end
end
end end
def self.list_by(attr, value, cached: true) def self.list_by(attr, value, cached: true)
@ -234,17 +228,12 @@ class ::CustomWizard::CustomField
external = [] external = []
CLASSES.keys.each do |klass| CLASSES.keys.each do |klass|
meta_data = klass.to_s.classify.constantize.send('custom_field_meta_data') meta_data = klass.to_s.classify.constantize.send("custom_field_meta_data")
if meta_data.present? if meta_data.present?
meta_data.each do |name, data| meta_data.each do |name, data|
unless list.any? { |field| field.name === name } unless list.any? { |field| field.name === name }
field = new( field = new("external", name: name, klass: klass, type: data.type)
'external',
name: name,
klass: klass,
type: data.type
)
external.push(field) external.push(field)
end end
end end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module ::CustomWizard module ::CustomWizard
PLUGIN_NAME ||= 'custom_wizard' PLUGIN_NAME ||= "custom_wizard"
class Engine < ::Rails::Engine class Engine < ::Rails::Engine
engine_name PLUGIN_NAME engine_name PLUGIN_NAME

Datei anzeigen

@ -1,5 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
module CustomWizard module CustomWizard
class SprocketsFileNotFound < StandardError; end class SprocketsFileNotFound < StandardError
class SprocketsEmptyPath < StandardError; end end
class SprocketsEmptyPath < StandardError
end
end end

Datei anzeigen

@ -3,11 +3,7 @@ module CustomWizardCustomFieldPreloader
def preload_custom_fields(objects, fields) def preload_custom_fields(objects, fields)
if objects.present? && cw_fields_enabled? if objects.present? && cw_fields_enabled?
@cw_klass = objects.first.class.name.underscore @cw_klass = objects.first.class.name.underscore
if cw_fields.any? cw_fields.each { |field| fields << field[:name] } if cw_fields.any?
cw_fields.each do |field|
fields << field[:name]
end
end
end end
super(objects, fields) super(objects, fields)
end end

Datei anzeigen

@ -31,10 +31,11 @@ module CustomWizardCustomFieldSerializer
end end
def get_cw_class def get_cw_class
self.class.ancestors.map do |klass| self
klass.to_s.underscore.gsub("_serializer", "") .class
end.select do |klass| .ancestors
CustomWizard::CustomField.serializers.include?(klass) .map { |klass| klass.to_s.underscore.gsub("_serializer", "") }
end.first .select { |klass| CustomWizard::CustomField.serializers.include?(klass) }
.first
end end
end end

Datei anzeigen

@ -4,9 +4,12 @@ module CustomWizardDiscourseTagging
def filter_allowed_tags(guardian, opts = {}) def filter_allowed_tags(guardian, opts = {})
if opts[:for_input].respond_to?(:dig) && (groups = opts.dig(:for_input, :groups)).present? if opts[:for_input].respond_to?(:dig) && (groups = opts.dig(:for_input, :groups)).present?
tag_group_array = groups.split(",") tag_group_array = groups.split(",")
filtered_tags = TagGroup.includes(:tags).where(name: tag_group_array).map do |tag_group| filtered_tags =
tag_group.tags.pluck(:name) TagGroup
end.flatten .includes(:tags)
.where(name: tag_group_array)
.map { |tag_group| tag_group.tags.pluck(:name) }
.flatten
opts[:only_tag_names] ||= [] opts[:only_tag_names] ||= []
opts[:only_tag_names].push(*filtered_tags) opts[:only_tag_names].push(*filtered_tags)

Datei anzeigen

@ -1,13 +1,14 @@
# frozen_string_literal: true # frozen_string_literal: true
module ExtraLocalesControllerCustomWizard module ExtraLocalesControllerCustomWizard
private def valid_bundle?(bundle) private def valid_bundle?(bundle)
super || begin super ||
return false unless bundle =~ /wizard/ && request.referer =~ /\/w\// begin
path = URI(request.referer).path return false unless bundle =~ /wizard/ && request.referer =~ %r{/w/}
wizard_path = path.split('/w/').last path = URI(request.referer).path
wizard_id = wizard_path.split('/').first wizard_path = path.split("/w/").last
return true if wizard_id == "qunit" wizard_id = wizard_path.split("/").first
CustomWizard::Template.exists?(wizard_id.underscore) return true if wizard_id == "qunit"
end CustomWizard::Template.exists?(wizard_id.underscore)
end
end end
end end

Datei anzeigen

@ -8,10 +8,8 @@ module CustomWizardGuardian
def wizard_can_edit_topic?(topic) def wizard_can_edit_topic?(topic)
created_by_wizard = !!topic.wizard_submission_id created_by_wizard = !!topic.wizard_submission_id
( (
is_my_own?(topic) && is_my_own?(topic) && created_by_wizard && can_see_topic?(topic) &&
created_by_wizard && can_create_post_on_topic?(topic)
can_see_topic?(topic) &&
can_create_post_on_topic?(topic)
) )
end end
end end

Datei anzeigen

@ -4,7 +4,7 @@ module InvitesControllerCustomWizard
if ::Wizard.user_requires_completion?(@user) if ::Wizard.user_requires_completion?(@user)
wizard_id = @user.redirect_to_wizard wizard_id = @user.redirect_to_wizard
if wizard_id && url != '/' if wizard_id && url != "/"
CustomWizard::Wizard.set_wizard_redirect(@user, wizard_id, url) CustomWizard::Wizard.set_wizard_redirect(@user, wizard_id, url)
url = "/w/#{wizard_id.dasherize}" url = "/w/#{wizard_id.dasherize}"
end end

Datei anzeigen

@ -1,8 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module CustomWizardUsersController module CustomWizardUsersController
def account_created def account_created
if current_user.present? && if current_user.present? && (wizard = CustomWizard::Wizard.after_signup(current_user))
(wizard = CustomWizard::Wizard.after_signup(current_user))
return redirect_to "/w/#{wizard.id.dasherize}" return redirect_to "/w/#{wizard.id.dasherize}"
end end
super super

Datei anzeigen

@ -27,12 +27,9 @@ class CustomWizard::Field
:preview_template, :preview_template,
:placeholder :placeholder
attr_accessor :index, attr_accessor :index, :step
:step
REQUIRES_USER = %w[ REQUIRES_USER = %w[upload]
upload
]
def initialize(attrs) def initialize(attrs)
@raw = attrs || {} @raw = attrs || {}
@ -64,9 +61,7 @@ class CustomWizard::Field
end end
def default_value def default_value
if @type == 'checkbox' false if @type == "checkbox"
false
end
end end
def self.types def self.types
@ -77,82 +72,90 @@ class CustomWizard::Field
prefill: nil, prefill: nil,
char_counter: nil, char_counter: nil,
validations: nil, validations: nil,
placeholder: nil placeholder: nil,
}, },
textarea: { textarea: {
min_length: nil, min_length: nil,
max_length: nil, max_length: nil,
prefill: nil, prefill: nil,
char_counter: nil, char_counter: nil,
placeholder: nil placeholder: nil,
}, },
composer: { composer: {
min_length: nil, min_length: nil,
max_length: nil, max_length: nil,
char_counter: nil, char_counter: nil,
placeholder: nil placeholder: nil,
},
text_only: {
}, },
text_only: {},
composer_preview: { composer_preview: {
preview_template: nil, preview_template: nil,
}, },
date: { date: {
format: "YYYY-MM-DD" format: "YYYY-MM-DD",
}, },
time: { time: {
format: "HH:mm" format: "HH:mm",
}, },
date_time: { date_time: {
format: "" format: "",
},
number: {
},
checkbox: {
}, },
number: {},
checkbox: {},
url: { url: {
min_length: nil min_length: nil,
}, },
upload: { upload: {
file_types: '.jpg,.jpeg,.png' file_types: ".jpg,.jpeg,.png",
}, },
dropdown: { dropdown: {
prefill: nil, prefill: nil,
content: nil content: nil,
}, },
tag: { tag: {
limit: nil, limit: nil,
prefill: nil, prefill: nil,
content: nil, content: nil,
tag_groups: nil, tag_groups: nil,
can_create_tag: false can_create_tag: false,
}, },
category: { category: {
limit: 1, limit: 1,
property: 'id', property: "id",
prefill: nil, prefill: nil,
content: nil content: nil,
}, },
topic: { topic: {
limit: 1, limit: 1,
prefill: nil, prefill: nil,
content: nil, content: nil,
category: nil category: nil,
}, },
group: { group: {
prefill: nil, prefill: nil,
content: nil content: nil,
},
user_selector: {
}, },
user_selector: {}
} }
end end
def self.require_assets def self.require_assets
Rails.logger.warn("Custom Wizard field regisration no longer requires asset registration. Support will be removed in v2.1.0.") Rails.logger.warn(
"Custom Wizard field regisration no longer requires asset registration. Support will be removed in v2.1.0.",
)
@require_assets ||= {} @require_assets ||= {}
end end
def self.register(type, plugin = nil, opts = {}, legacy_opts = {}) def self.register(type, plugin = nil, opts = {}, legacy_opts = {})
if opts.is_a?(Array) if opts.is_a?(Array)
Rails.logger.warn("Custom Wizard field regisration no longer requires asset registration. Support will be removed in v2.1.0.") Rails.logger.warn(
"Custom Wizard field regisration no longer requires asset registration. Support will be removed in v2.1.0.",
)
require_assets[plugin] = opts require_assets[plugin] = opts
opts = legacy_opts opts = legacy_opts

Datei anzeigen

@ -8,30 +8,28 @@ class CustomWizard::Log
PAGE_LIMIT = 100 PAGE_LIMIT = 100
def initialize(attrs) def initialize(attrs)
@date = attrs['date'] @date = attrs["date"]
@action = attrs['action'] @action = attrs["action"]
@message = attrs['message'] @message = attrs["message"]
@wizard_id = attrs['wizard_id'] @wizard_id = attrs["wizard_id"]
@username = attrs['username'] @username = attrs["username"]
end end
def self.create(wizard_id, action, username, message, date = Time.now) def self.create(wizard_id, action, username, message, date = Time.now)
log_id = SecureRandom.hex(12) log_id = SecureRandom.hex(12)
PluginStore.set('custom_wizard_log', PluginStore.set(
"custom_wizard_log",
log_id.to_s, log_id.to_s,
{ { date: date, wizard_id: wizard_id, action: action, username: username, message: message },
date: date,
wizard_id: wizard_id,
action: action,
username: username,
message: message
}
) )
end end
def self.list_query(wizard_id = nil) def self.list_query(wizard_id = nil)
query = PluginStoreRow.where("plugin_name = 'custom_wizard_log' AND (value::json->'date') IS NOT NULL") query =
PluginStoreRow.where(
"plugin_name = 'custom_wizard_log' AND (value::json->'date') IS NOT NULL",
)
query = query.where("(value::json->>'wizard_id') = ?", wizard_id) if wizard_id query = query.where("(value::json->>'wizard_id') = ?", wizard_id) if wizard_id
query.order("value::json->>'date' DESC") query.order("value::json->>'date' DESC")
end end
@ -43,9 +41,7 @@ class CustomWizard::Log
result = OpenStruct.new(logs: [], total: nil) result = OpenStruct.new(logs: [], total: nil)
result.total = logs.size result.total = logs.size
result.logs = logs.limit(limit) result.logs = logs.limit(limit).offset(page * limit).map { |r| self.new(JSON.parse(r.value)) }
.offset(page * limit)
.map { |r| self.new(JSON.parse(r.value)) }
result result
end end

Datei anzeigen

@ -2,45 +2,29 @@
class CustomWizard::Mapper class CustomWizard::Mapper
attr_accessor :inputs, :data, :user attr_accessor :inputs, :data, :user
USER_FIELDS = [ USER_FIELDS = %w[name username date_of_birth title locale trust_level email]
'name',
'username',
'date_of_birth',
'title',
'locale',
'trust_level',
'email'
]
USER_OPTION_FIELDS = [ USER_OPTION_FIELDS = %w[email_level email_messages_level email_digests]
'email_level',
'email_messages_level',
'email_digests'
]
PROFILE_FIELDS = [ PROFILE_FIELDS = %w[location website bio_raw]
'location',
'website',
'bio_raw'
]
def self.user_fields def self.user_fields
USER_FIELDS + USER_OPTION_FIELDS + PROFILE_FIELDS USER_FIELDS + USER_OPTION_FIELDS + PROFILE_FIELDS
end end
OPERATORS = { OPERATORS = {
equal: '==', equal: "==",
not_equal: "!=", not_equal: "!=",
greater: '>', greater: ">",
less: '<', less: "<",
greater_or_equal: '>=', greater_or_equal: ">=",
less_or_equal: '<=', less_or_equal: "<=",
regex: '=~', regex: "=~",
is: { is: {
present: "present?", present: "present?",
true: "==", true: "==",
false: "==" false: "==",
} },
} }
def initialize(params) def initialize(params)
@ -55,12 +39,12 @@ class CustomWizard::Mapper
perform_result = multiple ? [] : nil perform_result = multiple ? [] : nil
inputs.each do |input| inputs.each do |input|
input_type = input['type'] input_type = input["type"]
pairs = input['pairs'] pairs = input["pairs"]
if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment' if (input_type === "conditional" && validate_pairs(pairs)) || input_type === "assignment"
output = input['output'] output = input["output"]
output_type = input['output_type'] output_type = input["output_type"]
result = build_result(map_field(output, output_type), input_type) result = build_result(map_field(output, output_type), input_type)
@ -72,7 +56,7 @@ class CustomWizard::Mapper
end end
end end
if input_type === 'validation' if input_type === "validation"
result = build_result(validate_pairs(pairs), input_type) result = build_result(validate_pairs(pairs), input_type)
if multiple if multiple
@ -83,7 +67,7 @@ class CustomWizard::Mapper
end end
end end
if input_type === 'association' if input_type === "association"
result = build_result(map_pairs(pairs), input_type) result = build_result(map_pairs(pairs), input_type)
if multiple if multiple
@ -100,10 +84,7 @@ class CustomWizard::Mapper
def build_result(result, type) def build_result(result, type)
if @opts[:with_type] if @opts[:with_type]
{ { type: type, result: result }
type: type,
result: result
}
else else
result result
end end
@ -111,10 +92,10 @@ class CustomWizard::Mapper
def validate_pairs(pairs) def validate_pairs(pairs)
pairs.all? do |pair| pairs.all? do |pair|
connector = pair['connector'] connector = pair["connector"]
operator = map_operator(connector) operator = map_operator(connector)
key = map_field(pair['key'], pair['key_type']) key = map_field(pair["key"], pair["key_type"])
value = cast_value(map_field(pair['value'], pair['value_type']), key, connector) value = cast_value(map_field(pair["value"], pair["value_type"]), key, connector)
begin begin
validation_result(key, value, operator) validation_result(key, value, operator)
rescue NoMethodError rescue NoMethodError
@ -124,7 +105,7 @@ class CustomWizard::Mapper
end end
def cast_value(value, key, connector) def cast_value(value, key, connector)
if connector == 'regex' if connector == "regex"
Regexp.new(value) Regexp.new(value)
else else
if key.is_a?(String) if key.is_a?(String)
@ -143,7 +124,7 @@ class CustomWizard::Mapper
if operator.is_a?(Hash) && (operator = operator[value.to_sym]).present? if operator.is_a?(Hash) && (operator = operator[value.to_sym]).present?
if value == "present" if value == "present"
result = key.public_send(operator) result = key.public_send(operator)
elsif ["true", "false"].include?(value) elsif %w[true false].include?(value)
result = bool(key).public_send(operator, bool(value)) result = bool(key).public_send(operator, bool(value))
end end
elsif [key, value, operator].all? { |i| !i.nil? } elsif [key, value, operator].all? { |i| !i.nil? }
@ -152,7 +133,7 @@ class CustomWizard::Mapper
result = false result = false
end end
if operator == '=~' if operator == "=~"
result.nil? ? false : true result.nil? ? false : true
else else
result result
@ -163,22 +144,17 @@ class CustomWizard::Mapper
result = [] result = []
pairs.each do |pair| pairs.each do |pair|
key = map_field(pair['key'], pair['key_type']) key = map_field(pair["key"], pair["key_type"])
value = map_field(pair['value'], pair['value_type']) value = map_field(pair["value"], pair["value_type"])
if key && value result.push(key: key, value: value) if key && value
result.push(
key: key,
value: value
)
end
end end
result result
end end
def map_operator(connector) def map_operator(connector)
OPERATORS[connector.to_sym] || '==' OPERATORS[connector.to_sym] || "=="
end end
def map_field(value, type) def map_field(value, type)
@ -214,7 +190,7 @@ class CustomWizard::Mapper
user.send(value) user.send(value)
elsif USER_OPTION_FIELDS.include?(value) elsif USER_OPTION_FIELDS.include?(value)
user.user_option.send(value) user.user_option.send(value)
elsif value.include?('avatar') elsif value.include?("avatar")
get_avatar_url(value) get_avatar_url(value)
else else
nil nil
@ -223,7 +199,7 @@ class CustomWizard::Mapper
def map_user_field_options(value) def map_user_field_options(value)
if value.include?(User::USER_FIELD_PREFIX) if value.include?(User::USER_FIELD_PREFIX)
if field = UserField.find_by(id: value.split('_').last) if field = UserField.find_by(id: value.split("_").last)
field.user_field_options.map(&:value) field.user_field_options.map(&:value)
end end
end end
@ -232,22 +208,18 @@ class CustomWizard::Mapper
def interpolate(string, opts = { user: true, wizard: true, value: true, template: false }) def interpolate(string, opts = { user: true, wizard: true, value: true, template: false })
return string if string.blank? || string.frozen? return string if string.blank? || string.frozen?
if opts[:user] && @user.present? string.gsub!(/u\{(.*?)\}/) { |match| map_user_field($1) || "" } if opts[:user] && @user.present?
string.gsub!(/u\{(.*?)\}/) { |match| map_user_field($1) || '' }
end
if opts[:wizard] string.gsub!(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split(".")]) || "" } if opts[:wizard]
string.gsub!(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split('.')]) || '' }
end
if opts[:value] if opts[:value]
string.gsub!(/v\{(.*?)\}/) do |match| string.gsub!(/v\{(.*?)\}/) do |match|
attrs = $1.split(':') attrs = $1.split(":")
key = attrs.first key = attrs.first
format = attrs.last if attrs.length > 1 format = attrs.last if attrs.length > 1
result = '' result = ""
if key == 'time' if key == "time"
time_format = format.present? ? format : "%B %-d, %Y" time_format = format.present? ? format : "%B %-d, %Y"
result = Time.now.strftime(time_format) result = Time.now.strftime(time_format)
end end
@ -281,10 +253,10 @@ class CustomWizard::Mapper
end end
def get_avatar_url(value) def get_avatar_url(value)
parts = value.split('.') parts = value.split(".")
valid_sizes = Discourse.avatar_sizes.to_a valid_sizes = Discourse.avatar_sizes.to_a
if value === 'avatar' || parts.size === 1 || valid_sizes.exclude?(parts.last.to_i) if value === "avatar" || parts.size === 1 || valid_sizes.exclude?(parts.last.to_i)
user.small_avatar_url user.small_avatar_url
else else
user.avatar_template_url.gsub("{size}", parts.last) user.avatar_template_url.gsub("{size}", parts.last)

Datei anzeigen

@ -8,7 +8,7 @@ class CustomWizard::RealtimeValidation
types: [:text], types: [:text],
component: "similar-topics-validator", component: "similar-topics-validator",
backend: true, backend: true,
required_params: [] required_params: [],
} },
} }
end end

Datei anzeigen

@ -1,8 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::RealtimeValidation::Result class CustomWizard::RealtimeValidation::Result
attr_accessor :type, attr_accessor :type, :items, :serializer_opts
:items,
:serializer_opts
def initialize(type) def initialize(type)
@type = type @type = type

Datei anzeigen

@ -27,9 +27,7 @@ class CustomWizard::RealtimeValidation::SimilarTopics
result = CustomWizard::RealtimeValidation::Result.new(:similar_topic) result = CustomWizard::RealtimeValidation::Result.new(:similar_topic)
if title.length < SiteSetting.min_title_similar_length return result if title.length < SiteSetting.min_title_similar_length
return result
end
topics = Topic.similar_to(title, raw, user).to_a topics = Topic.similar_to(title, raw, user).to_a
topics.select! { |t| categories.include?(t.category.id.to_s) } if categories.present? topics.select! { |t| categories.include?(t.category.id.to_s) } if categories.present?

Datei anzeigen

@ -3,8 +3,7 @@
class CustomWizard::Step class CustomWizard::Step
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
attr_reader :id, attr_reader :id, :updater
:updater
attr_accessor :index, attr_accessor :index,
:title, :title,

Datei anzeigen

@ -14,18 +14,14 @@ class CustomWizard::StepUpdater
end end
def update def update
if SiteSetting.custom_wizard_enabled && if SiteSetting.custom_wizard_enabled && @step.present? && @step.updater.present? && success?
@step.present? &&
@step.updater.present? &&
success?
@step.updater.call(self) @step.updater.call(self)
CustomWizard::UserHistory.create( CustomWizard::UserHistory.create(
action: CustomWizard::UserHistory.actions[:step], action: CustomWizard::UserHistory.actions[:step],
actor_id: @wizard.actor_id, actor_id: @wizard.actor_id,
context: @wizard.id, context: @wizard.id,
subject: @step.id subject: @step.id,
) )
else else
false false

Datei anzeigen

@ -4,31 +4,25 @@ class CustomWizard::Submission
PAGE_LIMIT = 50 PAGE_LIMIT = 50
KEY ||= "submissions" KEY ||= "submissions"
META ||= %w(updated_at submitted_at route_to redirect_on_complete redirect_to) META ||= %w[updated_at submitted_at route_to redirect_on_complete redirect_to]
attr_reader :id, attr_reader :id, :wizard
:wizard
attr_accessor :fields, attr_accessor :fields, :permitted_param_keys
:permitted_param_keys
META.each do |attr| META.each { |attr| class_eval { attr_accessor attr } }
class_eval { attr_accessor attr }
end
def initialize(wizard, data = {}) def initialize(wizard, data = {})
@wizard = wizard @wizard = wizard
data = (data || {}).with_indifferent_access data = (data || {}).with_indifferent_access
@id = data['id'] || SecureRandom.hex(12) @id = data["id"] || SecureRandom.hex(12)
non_field_keys = META + ['id'] non_field_keys = META + ["id"]
@fields = data.except(*non_field_keys) || {} @fields = data.except(*non_field_keys) || {}
META.each do |attr| META.each { |attr| send("#{attr}=", data[attr]) if data[attr] }
send("#{attr}=", data[attr]) if data[attr]
end
@permitted_param_keys = data['permitted_param_keys'] || [] @permitted_param_keys = data["permitted_param_keys"] || []
end end
def save def save
@ -40,7 +34,7 @@ class CustomWizard::Submission
self.updated_at = Time.now.iso8601 self.updated_at = Time.now.iso8601
submissions.push(self) submissions.push(self)
submission_data = submissions.map { |submission| data_to_save(submission) } submission_data = submissions.map { |submission| data_to_save(submission) }
PluginStore.set("#{wizard.id}_#{KEY}", wizard.actor_id, submission_data) PluginStore.set("#{wizard.id}_#{KEY}", wizard.actor_id, submission_data)
end end
@ -49,9 +43,8 @@ class CustomWizard::Submission
end end
def validate_field_key(key) def validate_field_key(key)
wizard.field_ids.include?(key) || wizard.field_ids.include?(key) || wizard.action_ids.include?(key) ||
wizard.action_ids.include?(key) || permitted_param_keys.include?(key)
permitted_param_keys.include?(key)
end end
def fields_and_meta def fields_and_meta
@ -71,9 +64,7 @@ class CustomWizard::Submission
end end
def data_to_save(submission) def data_to_save(submission)
data = { data = { id: submission.id }
id: submission.id
}
data.merge!(submission.fields_and_meta) data.merge!(submission.fields_and_meta)
@ -103,21 +94,26 @@ class CustomWizard::Submission
def self.cleanup_incomplete_submissions(wizard) def self.cleanup_incomplete_submissions(wizard)
all_submissions = list(wizard) all_submissions = list(wizard)
sorted_submissions = all_submissions.submissions.sort_by do |submission| sorted_submissions =
zero_epoch_time = DateTime.strptime("0", '%s') all_submissions
[ .submissions
submission.submitted_at ? Time.iso8601(submission.submitted_at) : zero_epoch_time, .sort_by do |submission|
submission.updated_at ? Time.iso8601(submission.updated_at) : zero_epoch_time zero_epoch_time = DateTime.strptime("0", "%s")
] [
end.reverse submission.submitted_at ? Time.iso8601(submission.submitted_at) : zero_epoch_time,
submission.updated_at ? Time.iso8601(submission.updated_at) : zero_epoch_time,
]
end
.reverse
has_incomplete = false has_incomplete = false
valid_submissions = sorted_submissions.select do |submission| valid_submissions =
to_be_included = submission.submitted_at || !has_incomplete sorted_submissions.select do |submission|
has_incomplete = true if !submission.submitted_at to_be_included = submission.submitted_at || !has_incomplete
has_incomplete = true if !submission.submitted_at
to_be_included to_be_included
end end
valid_data = valid_submissions.map { |submission| submission.data_to_save(submission) } valid_data = valid_submissions.map { |submission| submission.data_to_save(submission) }
PluginStore.set("#{wizard.id}_#{KEY}", wizard.actor_id, valid_data) PluginStore.set("#{wizard.id}_#{KEY}", wizard.actor_id, valid_data)

Datei anzeigen

@ -2,128 +2,129 @@
require "discourse_subscription_client" require "discourse_subscription_client"
class CustomWizard::Subscription class CustomWizard::Subscription
PRODUCT_HIERARCHY = %w[ PRODUCT_HIERARCHY = %w[community standard business]
community
standard
business
]
def self.attributes def self.attributes
{ {
wizard: { wizard: {
required: { required: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
}, },
permitted: { permitted: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*', "!#{CustomWizard::Wizard::GUEST_GROUP_ID}"] community: ["*", "!#{CustomWizard::Wizard::GUEST_GROUP_ID}"],
}, },
restart_on_revisit: { restart_on_revisit: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
} },
}, },
step: { step: {
condition: { condition: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
}, },
required_data: { required_data: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
}, },
permitted_params: { permitted_params: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
} },
}, },
field: { field: {
condition: { condition: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
}, },
type: { type: {
none: ['text', 'textarea', 'text_only', 'date', 'time', 'date_time', 'number', 'checkbox', 'dropdown', 'upload'], none: %w[text textarea text_only date time date_time number checkbox dropdown upload],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
}, },
realtime_validations: { realtime_validations: {
none: [], none: [],
standard: ['*'], standard: ["*"],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
} },
}, },
action: { action: {
type: { type: {
none: ['create_topic', 'update_profile', 'open_composer', 'route_to'], none: %w[create_topic update_profile open_composer route_to],
standard: ['create_topic', 'update_profile', 'open_composer', 'route_to', 'send_message', 'watch_categories', 'watch_tags', 'add_to_group'], standard: %w[
business: ['*'], create_topic
community: ['*'] update_profile
} open_composer
route_to
send_message
watch_categories
watch_tags
add_to_group
],
business: ["*"],
community: ["*"],
},
}, },
custom_field: { custom_field: {
klass: { klass: {
none: ['topic', 'post'], none: %w[topic post],
standard: ['topic', 'post'], standard: %w[topic post],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
}, },
type: { type: {
none: ['string', 'boolean', 'integer'], none: %w[string boolean integer],
standard: ['string', 'boolean', 'integer'], standard: %w[string boolean integer],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
} },
}, },
api: { api: {
all: { all: {
none: [], none: [],
standard: [], standard: [],
business: ['*'], business: ["*"],
community: ['*'] community: ["*"],
} },
} },
} }
end end
attr_accessor :product_id, attr_accessor :product_id, :product_slug
:product_slug
def initialize(update = false) def initialize(update = false)
if update ::DiscourseSubscriptionClient::Subscriptions.update if update
::DiscourseSubscriptionClient::Subscriptions.update
end
result = ::DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard") result = ::DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard")
if result&.any? if result&.any?
ids_and_slugs = result.subscriptions.map do |subscription| ids_and_slugs =
{ result.subscriptions.map do |subscription|
id: subscription.product_id, { id: subscription.product_id, slug: result.products[subscription.product_id] }
slug: result.products[subscription.product_id] end
}
end
id_and_slug = ids_and_slugs.sort do |a, b| id_and_slug =
PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug]) ids_and_slugs
end.first .sort { |a, b| PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug]) }
.first
@product_id = id_and_slug[:id] @product_id = id_and_slug[:id]
@product_slug = id_and_slug[:slug] @product_slug = id_and_slug[:slug]
@ -182,7 +183,8 @@ class CustomWizard::Subscription
# TODO candidate for removal once code that depends on it externally is no longer used. # TODO candidate for removal once code that depends on it externally is no longer used.
def self.client_installed? def self.client_installed?
defined?(DiscourseSubscriptionClient) == 'constant' && DiscourseSubscriptionClient.class == Module defined?(DiscourseSubscriptionClient) == "constant" &&
DiscourseSubscriptionClient.class == Module
end end
def self.subscribed? def self.subscribed?
@ -219,10 +221,12 @@ class CustomWizard::Subscription
end end
def mapped_output(value) def mapped_output(value)
value.reduce([]) do |result, v| value
## We can only validate mapped assignment values at the moment .reduce([]) do |result, v|
result << v["output"] if v.is_a?(Hash) && v["type"] === "assignment" ## We can only validate mapped assignment values at the moment
result result << v["output"] if v.is_a?(Hash) && v["type"] === "assignment"
end.flatten result
end
.flatten
end end
end end

Datei anzeigen

@ -6,15 +6,12 @@ class CustomWizard::Template
AFTER_SIGNUP_CACHE_KEY ||= "after_signup_wizard_ids" AFTER_SIGNUP_CACHE_KEY ||= "after_signup_wizard_ids"
AFTER_TIME_CACHE_KEY ||= "after_time_wizard_ids" AFTER_TIME_CACHE_KEY ||= "after_time_wizard_ids"
attr_reader :data, attr_reader :data, :opts, :steps, :actions
:opts,
:steps,
:actions
def initialize(data) def initialize(data)
@data = data @data = data
@steps = data['steps'] || [] @steps = data["steps"] || []
@actions = data['actions'] || [] @actions = data["actions"] || []
end end
def save(opts = {}) def save(opts = {})
@ -64,7 +61,11 @@ class CustomWizard::Template
ensure_wizard_upload_references!(wizard_id) ensure_wizard_upload_references!(wizard_id)
PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id) PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id)
clear_user_wizard_redirect(wizard_id, after_time: !!wizard.after_time) clear_user_wizard_redirect(wizard_id, after_time: !!wizard.after_time)
related_custom_fields = CategoryCustomField.where(name: 'create_topic_wizard', value: wizard.name.parameterize(separator: "_")) related_custom_fields =
CategoryCustomField.where(
name: "create_topic_wizard",
value: wizard.name.parameterize(separator: "_"),
)
related_custom_fields.destroy_all related_custom_fields.destroy_all
end end
@ -74,7 +75,7 @@ class CustomWizard::Template
end end
def self.exists?(wizard_id) def self.exists?(wizard_id)
PluginStoreRow.exists?(plugin_name: 'custom_wizard', key: wizard_id) PluginStoreRow.exists?(plugin_name: "custom_wizard", key: wizard_id)
end end
def self.list(setting: nil, query_str: nil, order: :id) def self.list(setting: nil, query_str: nil, order: :id)
@ -82,15 +83,13 @@ class CustomWizard::Template
query += " AND (value::json ->> '#{setting}')::boolean IS TRUE" if setting query += " AND (value::json ->> '#{setting}')::boolean IS TRUE" if setting
query += " #{query_str}" if query_str query += " #{query_str}" if query_str
PluginStoreRow.where(query).order(order) PluginStoreRow
.where(query)
.order(order)
.reduce([]) do |result, record| .reduce([]) do |result, record|
attrs = JSON.parse(record.value) attrs = JSON.parse(record.value)
if attrs.present? && if attrs.present? && attrs.is_a?(Hash) && attrs["id"].present? && attrs["name"].present?
attrs.is_a?(Hash) &&
attrs['id'].present? &&
attrs['name'].present?
result.push(attrs) result.push(attrs)
end end
@ -99,25 +98,24 @@ class CustomWizard::Template
end end
def self.clear_user_wizard_redirect(wizard_id, after_time: false) def self.clear_user_wizard_redirect(wizard_id, after_time: false)
UserCustomField.where(name: 'redirect_to_wizard', value: wizard_id).destroy_all UserCustomField.where(name: "redirect_to_wizard", value: wizard_id).destroy_all
if after_time Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id) if after_time
Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id)
end
end end
def self.after_signup_ids def self.after_signup_ids
::CustomWizard::Cache.wrap(AFTER_SIGNUP_CACHE_KEY) do ::CustomWizard::Cache.wrap(AFTER_SIGNUP_CACHE_KEY) do
list(setting: 'after_signup').map { |t| t['id'] } list(setting: "after_signup").map { |t| t["id"] }
end end
end end
def self.after_time_ids def self.after_time_ids
::CustomWizard::Cache.wrap(AFTER_TIME_CACHE_KEY) do ::CustomWizard::Cache.wrap(AFTER_TIME_CACHE_KEY) do
list( list(
setting: 'after_time', setting: "after_time",
query_str: "AND (value::json ->> 'after_time_scheduled')::timestamp < '#{Time.now}'::timestamp" query_str:
).map { |t| t['id'] } "AND (value::json ->> 'after_time_scheduled')::timestamp < '#{Time.now}'::timestamp",
).map { |t| t["id"] }
end end
end end
@ -137,7 +135,7 @@ class CustomWizard::Template
UploadReference.ensure_exist!( UploadReference.ensure_exist!(
upload_ids: wizard_upload_ids, upload_ids: wizard_upload_ids,
target_type: "PluginStoreRow", target_type: "PluginStoreRow",
target_id: wizard_record.id target_id: wizard_record.id,
) )
end end
end end
@ -151,15 +149,11 @@ class CustomWizard::Template
def prepare_data def prepare_data
@data[:steps].each do |step| @data[:steps].each do |step|
if step[:raw_description] step[:description] = step[:raw_description] if step[:raw_description]
step[:description] = step[:raw_description]
end
remove_non_mapped_index(step) remove_non_mapped_index(step)
step[:fields].each do |field| step[:fields].each { |field| remove_non_mapped_index(field) }
remove_non_mapped_index(field)
end
end end
end end
@ -191,9 +185,7 @@ class CustomWizard::Template
end end
def remove_non_mapped_index(object) def remove_non_mapped_index(object)
if !object[:index].is_a?(Array) object.delete(:index) if !object[:index].is_a?(Array)
object.delete(:index)
end
end end
def ensure_wizard_upload_references! def ensure_wizard_upload_references!

Datei anzeigen

@ -15,26 +15,18 @@ class CustomWizard::UserHistory
end end
def self.actions def self.actions
@actions ||= @actions ||= Enum.new(step: UserHistory.actions[:custom_wizard_step])
Enum.new(
step: UserHistory.actions[:custom_wizard_step]
)
end end
def self.where_opts(actor_id, action, context, subject) def self.where_opts(actor_id, action, context, subject)
opts = { opts = { context: context }
context: context
}
opts[:action] = action if action opts[:action] = action if action
opts[:subject] = subject if subject opts[:subject] = subject if subject
add_actor(opts, actor_id) add_actor(opts, actor_id)
end end
def self.create_opts(actor_id, action, context, subject) def self.create_opts(actor_id, action, context, subject)
opts = { opts = { action: action, context: context }
action: action,
context: context
}
opts[:subject] = subject if subject opts[:subject] = subject if subject
add_actor(opts, actor_id) add_actor(opts, actor_id)
end end

Datei anzeigen

@ -48,12 +48,7 @@ class CustomWizard::TemplateValidator
end end
def self.required def self.required
{ { wizard: %w[id name steps], step: ["id"], field: %w[id type], action: %w[id type] }
wizard: ['id', 'name', 'steps'],
step: ['id'],
field: ['id', 'type'],
action: ['id', 'type']
}
end end
private private
@ -71,7 +66,8 @@ class CustomWizard::TemplateValidator
value = object[property] value = object[property]
if !@subscription.includes?(type, property.to_sym, value) if !@subscription.includes?(type, property.to_sym, value)
errors.add :base, I18n.t("wizard.validation.subscription", type: type.to_s, property: property) errors.add :base,
I18n.t("wizard.validation.subscription", type: type.to_s, property: property)
end end
end end
end end
@ -83,9 +79,9 @@ class CustomWizard::TemplateValidator
end end
def validate_guests(object, type) def validate_guests(object, type)
guests_permitted = @data[:permitted] && @data[:permitted].any? do |m| guests_permitted =
m["output"]&.include?(CustomWizard::Wizard::GUEST_GROUP_ID) @data[:permitted] &&
end @data[:permitted].any? { |m| m["output"]&.include?(CustomWizard::Wizard::GUEST_GROUP_ID) }
return unless guests_permitted return unless guests_permitted
if type === :action && CustomWizard::Action::REQUIRES_USER.include?(object[:type]) if type === :action && CustomWizard::Action::REQUIRES_USER.include?(object[:type])
@ -100,11 +96,14 @@ class CustomWizard::TemplateValidator
def validate_after_signup def validate_after_signup
return unless ActiveRecord::Type::Boolean.new.cast(@data[:after_signup]) return unless ActiveRecord::Type::Boolean.new.cast(@data[:after_signup])
other_after_signup = CustomWizard::Template.list(setting: 'after_signup') other_after_signup =
.select { |template| template['id'] != @data[:id] } CustomWizard::Template
.list(setting: "after_signup")
.select { |template| template["id"] != @data[:id] }
if other_after_signup.any? if other_after_signup.any?
errors.add :base, I18n.t("wizard.validation.after_signup", wizard_id: other_after_signup.first['id']) errors.add :base,
I18n.t("wizard.validation.after_signup", wizard_id: other_after_signup.first["id"])
end end
end end
@ -132,21 +131,17 @@ class CustomWizard::TemplateValidator
end end
def validate_liquid_template(object, type) def validate_liquid_template(object, type)
%w[ %w[description raw_description placeholder preview_template post_template].each do |field|
description
raw_description
placeholder
preview_template
post_template
].each do |field|
if template = object[field] if template = object[field]
result = is_liquid_template_valid?(template) result = is_liquid_template_valid?(template)
unless "valid" == result unless "valid" == result
error = I18n.t("wizard.validation.liquid_syntax_error", error =
attribute: "#{object[:id]}.#{field}", I18n.t(
message: result "wizard.validation.liquid_syntax_error",
) attribute: "#{object[:id]}.#{field}",
message: result,
)
errors.add :base, error errors.add :base, error
end end
end end
@ -156,7 +151,7 @@ class CustomWizard::TemplateValidator
def is_liquid_template_valid?(template) def is_liquid_template_valid?(template)
begin begin
Liquid::Template.parse(template) Liquid::Template.parse(template)
'valid' "valid"
rescue Liquid::SyntaxError => error rescue Liquid::SyntaxError => error
error.message error.message
end end

Datei anzeigen

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'addressable/uri' require "addressable/uri"
class ::CustomWizard::UpdateValidator class ::CustomWizard::UpdateValidator
attr_reader :updater attr_reader :updater
@ -9,13 +9,11 @@ class ::CustomWizard::UpdateValidator
end end
def perform def perform
updater.step.fields.each do |field| updater.step.fields.each { |field| validate_field(field) }
validate_field(field)
end
end end
def validate_field(field) def validate_field(field)
return if field.type == 'text_only' return if field.type == "text_only"
field_id = field.id.to_s field_id = field.id.to_s
value = @updater.submission[field_id] value = @updater.submission[field_id]
@ -29,43 +27,48 @@ class ::CustomWizard::UpdateValidator
format = field.format format = field.format
if required && !value if required && !value
@updater.errors.add(field_id, I18n.t('wizard.field.required', label: label)) @updater.errors.add(field_id, I18n.t("wizard.field.required", label: label))
end end
if value.is_a?(String) && (stripped_length = value.strip.length) > 0 if value.is_a?(String) && (stripped_length = value.strip.length) > 0
if min_length.present? && stripped_length < min_length.to_i if min_length.present? && stripped_length < min_length.to_i
@updater.errors.add(field_id, I18n.t('wizard.field.too_short', label: label, min: min_length.to_i)) @updater.errors.add(
field_id,
I18n.t("wizard.field.too_short", label: label, min: min_length.to_i),
)
end end
if max_length.present? && stripped_length > max_length.to_i if max_length.present? && stripped_length > max_length.to_i
@updater.errors.add(field_id, I18n.t('wizard.field.too_long', label: label, max: max_length.to_i)) @updater.errors.add(
field_id,
I18n.t("wizard.field.too_long", label: label, max: max_length.to_i),
)
end end
end end
if is_url_type(field) && value.present? && !check_if_url(value) if is_url_type(field) && value.present? && !check_if_url(value)
@updater.errors.add(field_id, I18n.t('wizard.field.not_url', label: label)) @updater.errors.add(field_id, I18n.t("wizard.field.not_url", label: label))
end end
if type === 'checkbox' @updater.submission[field_id] = standardise_boolean(value) if type === "checkbox"
@updater.submission[field_id] = standardise_boolean(value)
if type === "upload" && value.present? && !validate_file_type(value, file_types)
@updater.errors.add(
field_id,
I18n.t("wizard.field.invalid_file", label: label, types: file_types),
)
end end
if type === 'upload' && value.present? && !validate_file_type(value, file_types) if %w[date date_time].include?(type) && value.present? && !validate_date(value, format)
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_file', label: label, types: file_types)) @updater.errors.add(field_id, I18n.t("wizard.field.invalid_date"))
end end
if ['date', 'date_time'].include?(type) && value.present? && !validate_date(value, format) if type === "time" && value.present? && !validate_time(value)
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_date')) @updater.errors.add(field_id, I18n.t("wizard.field.invalid_time"))
end
if type === 'time' && value.present? && !validate_time(value)
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_time'))
end end
self.class.field_validators.each do |validator| self.class.field_validators.each do |validator|
if type === validator[:type] validator[:block].call(field, value, @updater) if type === validator[:type]
validator[:block].call(field, value, @updater)
end
end end
end end
@ -85,9 +88,10 @@ class ::CustomWizard::UpdateValidator
private private
def validate_file_type(value, file_types) def validate_file_type(value, file_types)
file_types.split(',') file_types
.map { |t| t.gsub('.', '') } .split(",")
.include?(File.extname(value['original_filename'])[1..-1]) .map { |t| t.gsub(".", "") }
.include?(File.extname(value["original_filename"])[1..-1])
end end
def validate_date(value, format) def validate_date(value, format)
@ -104,14 +108,14 @@ class ::CustomWizard::UpdateValidator
end end
def is_text_type(field) def is_text_type(field)
['text', 'textarea', 'composer'].include? field.type %w[text textarea composer].include? field.type
end end
def is_url_type(field) def is_url_type(field)
['url'].include? field.type ["url"].include? field.type
end end
SCHEMES ||= %w(http https) SCHEMES ||= %w[http https]
def check_if_url(url) def check_if_url(url)
parsed = Addressable::URI.parse(url) or return false parsed = Addressable::URI.parse(url) or return false

Datei anzeigen

@ -1,8 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
require_dependency 'wizard/step' require_dependency "wizard/step"
require_dependency 'wizard/field' require_dependency "wizard/field"
require_dependency 'wizard/step_updater' require_dependency "wizard/step_updater"
require_dependency 'wizard/builder' require_dependency "wizard/builder"
class CustomWizard::Wizard class CustomWizard::Wizard
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
@ -33,7 +33,7 @@ class CustomWizard::Wizard
:submissions, :submissions,
:template :template
attr_reader :all_step_ids attr_reader :all_step_ids
GUEST_ID_PREFIX ||= "guest" GUEST_ID_PREFIX ||= "guest"
GUEST_GROUP_ID = -1 GUEST_GROUP_ID = -1
@ -47,44 +47,40 @@ class CustomWizard::Wizard
attrs = attrs.with_indifferent_access attrs = attrs.with_indifferent_access
@id = attrs['id'] @id = attrs["id"]
@name = attrs['name'] @name = attrs["name"]
@background = attrs['background'] @background = attrs["background"]
@save_submissions = cast_bool(attrs['save_submissions']) @save_submissions = cast_bool(attrs["save_submissions"])
@multiple_submissions = cast_bool(attrs['multiple_submissions']) @multiple_submissions = cast_bool(attrs["multiple_submissions"])
@prompt_completion = cast_bool(attrs['prompt_completion']) @prompt_completion = cast_bool(attrs["prompt_completion"])
@restart_on_revisit = cast_bool(attrs['restart_on_revisit']) @restart_on_revisit = cast_bool(attrs["restart_on_revisit"])
@resume_on_revisit = cast_bool(attrs['resume_on_revisit']) @resume_on_revisit = cast_bool(attrs["resume_on_revisit"])
@after_signup = cast_bool(attrs['after_signup']) @after_signup = cast_bool(attrs["after_signup"])
@after_time = cast_bool(attrs['after_time']) @after_time = cast_bool(attrs["after_time"])
@after_time_scheduled = attrs['after_time_scheduled'] @after_time_scheduled = attrs["after_time_scheduled"]
@required = cast_bool(attrs['required']) @required = cast_bool(attrs["required"])
@permitted = attrs['permitted'] || nil @permitted = attrs["permitted"] || nil
@theme_id = attrs['theme_id'] @theme_id = attrs["theme_id"]
if attrs['theme'].present? if attrs["theme"].present?
theme = ::Theme.find_by(name: attrs['theme']) theme = ::Theme.find_by(name: attrs["theme"])
@theme_id = theme.id if theme @theme_id = theme.id if theme
end end
@first_step = nil @first_step = nil
@steps = [] @steps = []
if attrs['steps'].present? if attrs["steps"].present?
@step_ids = @all_step_ids = attrs['steps'].map { |s| s['id'] } @step_ids = @all_step_ids = attrs["steps"].map { |s| s["id"] }
@field_ids = [] @field_ids = []
attrs['steps'].each do |step| attrs["steps"].each do |step|
if step['fields'].present? step["fields"].each { |field| @field_ids << field["id"] } if step["fields"].present?
step['fields'].each do |field|
@field_ids << field['id']
end
end
end end
end end
@actions = attrs['actions'] || [] @actions = attrs["actions"] || []
@action_ids = @actions.map { |a| a['id'] } @action_ids = @actions.map { |a| a["id"] }
@template = attrs @template = attrs
end end
@ -137,13 +133,9 @@ class CustomWizard::Wizard
step.index = index step.index = index
if index === (steps.length - 1) step.conditional_final_step = true if index === (steps.length - 1)
step.conditional_final_step = true
end
if index === (all_step_ids.length - 1) step.last_step = true if index === (all_step_ids.length - 1)
step.last_step = true
end
if !@restart_on_revisit && step.previous && step.previous.id === last_completed_step_id if !@restart_on_revisit && step.previous && step.previous.id === last_completed_step_id
@start = step.id @start = step.id
@ -154,12 +146,16 @@ class CustomWizard::Wizard
def last_completed_step_id def last_completed_step_id
return nil unless actor_id && unfinished? return nil unless actor_id && unfinished?
last_completed_step = CustomWizard::UserHistory.where( last_completed_step =
actor_id: actor_id, CustomWizard::UserHistory
action: CustomWizard::UserHistory.actions[:step], .where(
context: id, actor_id: actor_id,
subject: all_step_ids action: CustomWizard::UserHistory.actions[:step],
).order("created_at").last context: id,
subject: all_step_ids,
)
.order("created_at")
.last
last_completed_step&.subject last_completed_step&.subject
end end
@ -178,11 +174,12 @@ class CustomWizard::Wizard
return nil unless actor_id return nil unless actor_id
return false if last_submission&.submitted? return false if last_submission&.submitted?
most_recent = CustomWizard::UserHistory.where( most_recent =
actor_id: actor_id, CustomWizard::UserHistory
action: CustomWizard::UserHistory.actions[:step], .where(actor_id: actor_id, action: CustomWizard::UserHistory.actions[:step], context: id)
context: id, .distinct
).distinct.order('updated_at DESC').first .order("updated_at DESC")
.first
if most_recent && most_recent.subject == "reset" if most_recent && most_recent.subject == "reset"
false false
@ -197,11 +194,12 @@ class CustomWizard::Wizard
return nil unless actor_id return nil unless actor_id
return true if last_submission&.submitted? return true if last_submission&.submitted?
history = CustomWizard::UserHistory.where( history =
actor_id: actor_id, CustomWizard::UserHistory.where(
action: CustomWizard::UserHistory.actions[:step], actor_id: actor_id,
context: id action: CustomWizard::UserHistory.actions[:step],
) context: id,
)
if after_time && multiple_submissions if after_time && multiple_submissions
history = history.where("updated_at > ?", after_time_scheduled) history = history.where("updated_at > ?", after_time_scheduled)
@ -216,26 +214,27 @@ class CustomWizard::Wizard
return true if user && ((always_allow_admin && user.admin?) || permitted.blank?) return true if user && ((always_allow_admin && user.admin?) || permitted.blank?)
return false if !user && permitted.blank? return false if !user && permitted.blank?
mapper = CustomWizard::Mapper.new( mapper =
inputs: permitted, CustomWizard::Mapper.new(
user: user, inputs: permitted,
opts: { user: user,
with_type: true, opts: {
multiple: true with_type: true,
} multiple: true,
).perform },
).perform
return true if mapper.blank? return true if mapper.blank?
mapper.all? do |m| mapper.all? do |m|
if !user if !user
m[:type] === 'assignment' && [*m[:result]].include?(GUEST_GROUP_ID) m[:type] === "assignment" && [*m[:result]].include?(GUEST_GROUP_ID)
else else
if m[:type] === 'assignment' if m[:type] === "assignment"
[*m[:result]].include?(GUEST_GROUP_ID) || [*m[:result]].include?(GUEST_GROUP_ID) ||
[*m[:result]].include?(Group::AUTO_GROUPS[:everyone]) || [*m[:result]].include?(Group::AUTO_GROUPS[:everyone]) ||
GroupUser.exists?(group_id: m[:result], user_id: user.id) GroupUser.exists?(group_id: m[:result], user_id: user.id)
elsif m[:type] === 'validation' elsif m[:type] === "validation"
m[:result] m[:result]
else else
true true
@ -259,7 +258,7 @@ class CustomWizard::Wizard
action: CustomWizard::UserHistory.actions[:step], action: CustomWizard::UserHistory.actions[:step],
actor_id: actor_id, actor_id: actor_id,
context: id, context: id,
subject: "reset" subject: "reset",
) )
end end
@ -275,11 +274,9 @@ class CustomWizard::Wizard
@action_ids = [] @action_ids = []
@actions.each do |action| @actions.each do |action|
if action['run_after'].blank? || if action["run_after"].blank? || action["run_after"] === "wizard_completion" ||
action['run_after'] === 'wizard_completion' || step_ids.include?(action["run_after"])
step_ids.include?(action['run_after']) @action_ids << action["id"]
@action_ids << action['id']
end end
end end
end end
@ -293,14 +290,15 @@ class CustomWizard::Wizard
end end
def current_submission def current_submission
@current_submission ||= begin @current_submission ||=
if submissions.present? begin
unsubmitted = submissions.select { |submission| !submission.submitted_at } if submissions.present?
unsubmitted.present? ? unsubmitted.first : CustomWizard::Submission.new(self) unsubmitted = submissions.select { |submission| !submission.submitted_at }
else unsubmitted.present? ? unsubmitted.first : CustomWizard::Submission.new(self)
CustomWizard::Submission.new(self) else
CustomWizard::Submission.new(self)
end
end end
end
end end
def cleanup_on_complete! def cleanup_on_complete!
@ -317,9 +315,7 @@ class CustomWizard::Wizard
def cleanup_on_skip! def cleanup_on_skip!
remove_user_redirect remove_user_redirect
if current_submission.present? current_submission.remove if current_submission.present?
current_submission.remove
end
reset reset
end end
@ -328,7 +324,7 @@ class CustomWizard::Wizard
return if user.blank? return if user.blank?
if id == user.redirect_to_wizard if id == user.redirect_to_wizard
user.custom_fields.delete('redirect_to_wizard') user.custom_fields.delete("redirect_to_wizard")
user.save_custom_fields(true) user.save_custom_fields(true)
end end
end end
@ -344,42 +340,33 @@ class CustomWizard::Wizard
def self.list(user, template_opts = {}, not_completed = false) def self.list(user, template_opts = {}, not_completed = false)
return [] unless user return [] unless user
CustomWizard::Template.list(**template_opts).reduce([]) do |result, template| CustomWizard::Template
wizard = new(template, user) .list(**template_opts)
result.push(wizard) if wizard.permitted? && ( .reduce([]) do |result, template|
!not_completed || !wizard.completed? wizard = new(template, user)
) result.push(wizard) if wizard.permitted? && (!not_completed || !wizard.completed?)
result result
end end
end end
def self.after_signup(user) def self.after_signup(user)
wizards = list( wizards =
user, list(
{ user,
setting: 'after_signup', { setting: "after_signup", order: "(value::json ->> 'permitted') IS NOT NULL DESC" },
order: "(value::json ->> 'permitted') IS NOT NULL DESC" )
}
)
wizards.any? ? wizards.first : false wizards.any? ? wizards.first : false
end end
def self.prompt_completion(user) def self.prompt_completion(user)
wizards = list( wizards =
user, list(
{ user,
setting: 'prompt_completion', { setting: "prompt_completion", order: "(value::json ->> 'permitted') IS NOT NULL DESC" },
order: "(value::json ->> 'permitted') IS NOT NULL DESC" true,
}, )
true
)
if wizards.any? if wizards.any?
wizards.map do |w| wizards.map { |w| { id: w.id, name: w.name } }
{
id: w.id,
name: w.name
}
end
else else
false false
end end
@ -389,7 +376,7 @@ class CustomWizard::Wizard
wizard = self.create(wizard_id, user) wizard = self.create(wizard_id, user)
if wizard.can_access?(always_allow_admin: false) if wizard.can_access?(always_allow_admin: false)
user.custom_fields['redirect_to_wizard'] = wizard_id user.custom_fields["redirect_to_wizard"] = wizard_id
user.save_custom_fields(true) user.save_custom_fields(true)
else else
false false

Datei anzeigen

@ -13,7 +13,7 @@ module DiscoursePluginStatistics
step: { step: {
required_data: 0, required_data: 0,
permitted_params: 0, permitted_params: 0,
force_final: 0 force_final: 0,
}, },
field: { field: {
condition: 0, condition: 0,
@ -37,7 +37,7 @@ module DiscoursePluginStatistics
group: 0, group: 0,
user_selector: 0, user_selector: 0,
}, },
realtime_validations: 0 realtime_validations: 0,
}, },
action: { action: {
type: { type: {
@ -52,47 +52,40 @@ module DiscoursePluginStatistics
add_to_group: 0, add_to_group: 0,
create_group: 0, create_group: 0,
create_category: 0, create_category: 0,
} },
} },
} }
increment_feature_count = lambda do |type, key, value| increment_feature_count =
if key == 'type' lambda do |type, key, value|
if !subscription_features[type.to_sym][:type][value.to_sym].nil? if key == "type"
subscription_features[type.to_sym][:type][value.to_sym] += 1 if !subscription_features[type.to_sym][:type][value.to_sym].nil?
end subscription_features[type.to_sym][:type][value.to_sym] += 1
else end
if !subscription_features[type.to_sym][key.to_sym].nil? else
subscription_features[type.to_sym][key.to_sym] += 1 if !subscription_features[type.to_sym][key.to_sym].nil?
end subscription_features[type.to_sym][key.to_sym] += 1
end
end
CustomWizard::Template.list.each do |template|
template.each do |key, value|
increment_feature_count.call(:wizard, key, value)
end
template['steps'].each do |step|
step.each do |key, value|
increment_feature_count.call(:step, key, value)
end
step['fields'].each do |field|
field.each do |key, value|
increment_feature_count.call(:field, key, value)
end end
end end
end end
template['actions'].each do |action|
action.each do |key, value| CustomWizard::Template.list.each do |template|
increment_feature_count.call(:action, key, value) template.each { |key, value| increment_feature_count.call(:wizard, key, value) }
template["steps"].each do |step|
step.each { |key, value| increment_feature_count.call(:step, key, value) }
step["fields"].each do |field|
field.each { |key, value| increment_feature_count.call(:field, key, value) }
end end
end end
template["actions"].each do |action|
action.each { |key, value| increment_feature_count.call(:action, key, value) }
end
end end
{ {
total_wizards: CustomWizard::Template.list.size, total_wizards: CustomWizard::Template.list.size,
subscription_type: CustomWizard::Subscription.type.to_s, subscription_type: CustomWizard::Subscription.type.to_s,
subscription_features: subscription_features subscription_features: subscription_features,
} }
end end
end end

Datei anzeigen

@ -1,19 +1,19 @@
# frozen_string_literal: true # frozen_string_literal: true
# name: discourse-custom-wizard # name: discourse-custom-wizard
# about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more. # about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more.
# version: 2.8.11 # version: 2.8.12
# authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever, Juan Marcos Gutierrez Ramos # authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever, Juan Marcos Gutierrez Ramos
# url: https://github.com/paviliondev/discourse-custom-wizard # url: https://github.com/paviliondev/discourse-custom-wizard
# contact_emails: development@pavilion.tech # contact_emails: development@pavilion.tech
# subscription_url: https://coop.pavilion.tech # subscription_url: https://coop.pavilion.tech
# meta_topic_id: 73345 # meta_topic_id: 73345
gem 'liquid', '5.5.0', require: true gem "liquid", "5.5.0", require: true
gem "discourse_subscription_client", "0.1.6", require_name: "discourse_subscription_client" gem "discourse_subscription_client", "0.1.6", require_name: "discourse_subscription_client"
gem 'discourse_plugin_statistics', '0.1.0.pre7', require: true gem "discourse_plugin_statistics", "0.1.0.pre7", require: true
register_asset 'stylesheets/common/admin.scss' register_asset "stylesheets/common/admin.scss"
register_asset 'stylesheets/common/wizard.scss' register_asset "stylesheets/common/wizard.scss"
register_svg_icon 'pavilion-logo' register_svg_icon "pavilion-logo"
register_svg_icon "hat-wizard" register_svg_icon "hat-wizard"
enabled_site_setting :custom_wizard_enabled enabled_site_setting :custom_wizard_enabled
@ -102,24 +102,18 @@ after_initialize do
../lib/custom_wizard/extensions/custom_field/serializer.rb ../lib/custom_wizard/extensions/custom_field/serializer.rb
../lib/custom_wizard/extensions/custom_field/extension.rb ../lib/custom_wizard/extensions/custom_field/extension.rb
../lib/custom_wizard/extensions/discourse_tagging.rb ../lib/custom_wizard/extensions/discourse_tagging.rb
].each do |path| ].each { |path| load File.expand_path(path, __FILE__) }
load File.expand_path(path, __FILE__)
end
Liquid::Template.error_mode = :strict Liquid::Template.error_mode = :strict
# preloaded category custom fields # preloaded category custom fields
%w[ %w[create_topic_wizard].each do |custom_field|
create_topic_wizard
].each do |custom_field|
Site.preloaded_category_custom_fields << custom_field Site.preloaded_category_custom_fields << custom_field
end end
Liquid::Template.register_filter(::CustomWizard::LiquidFilter::FirstNonEmpty) Liquid::Template.register_filter(::CustomWizard::LiquidFilter::FirstNonEmpty)
add_to_class(:topic, :wizard_submission_id) do add_to_class(:topic, :wizard_submission_id) { custom_fields["wizard_submission_id"] }
custom_fields['wizard_submission_id']
end
add_class_method(:wizard, :user_requires_completion?) do |user| add_class_method(:wizard, :user_requires_completion?) do |user|
wizard_result = self.new(user).requires_completion? wizard_result = self.new(user).requires_completion?
@ -127,10 +121,7 @@ after_initialize do
custom_redirect = false custom_redirect = false
if user && if user && user.first_seen_at.blank? && wizard = CustomWizard::Wizard.after_signup(user)
user.first_seen_at.blank? &&
wizard = CustomWizard::Wizard.after_signup(user)
if !wizard.completed? if !wizard.completed?
custom_redirect = true custom_redirect = true
CustomWizard::Wizard.set_user_redirect(wizard.id, user) CustomWizard::Wizard.set_user_redirect(wizard.id, user)
@ -141,8 +132,8 @@ after_initialize do
end end
add_to_class(:user, :redirect_to_wizard) do add_to_class(:user, :redirect_to_wizard) do
if custom_fields['redirect_to_wizard'].present? if custom_fields["redirect_to_wizard"].present?
custom_fields['redirect_to_wizard'] custom_fields["redirect_to_wizard"]
else else
nil nil
end end
@ -156,9 +147,7 @@ after_initialize do
end end
end end
add_to_serializer(:current_user, :redirect_to_wizard) do add_to_serializer(:current_user, :redirect_to_wizard) { object.redirect_to_wizard }
object.redirect_to_wizard
end
on(:user_approved) do |user| on(:user_approved) do |user|
if wizard = CustomWizard::Wizard.after_signup(user) if wizard = CustomWizard::Wizard.after_signup(user)
@ -167,16 +156,16 @@ after_initialize do
end end
add_to_class(:application_controller, :redirect_to_wizard_if_required) do add_to_class(:application_controller, :redirect_to_wizard_if_required) do
@excluded_routes ||= SiteSetting.wizard_redirect_exclude_paths.split('|') + ['/w/'] @excluded_routes ||= SiteSetting.wizard_redirect_exclude_paths.split("|") + ["/w/"]
url = request.referer || request.original_url url = request.referer || request.original_url
excluded_route = @excluded_routes.any? { |str| /#{str}/ =~ url } excluded_route = @excluded_routes.any? { |str| /#{str}/ =~ url }
not_api = request.format === 'text/html' not_api = request.format === "text/html"
if not_api && !excluded_route if not_api && !excluded_route
wizard_id = current_user.redirect_to_wizard wizard_id = current_user.redirect_to_wizard
if CustomWizard::Template.can_redirect_users?(wizard_id) if CustomWizard::Template.can_redirect_users?(wizard_id)
if url !~ /\/w\// && url !~ /\/invites\// if url !~ %r{/w/} && url !~ %r{/invites/}
CustomWizard::Wizard.set_wizard_redirect(current_user, wizard_id, url) CustomWizard::Wizard.set_wizard_redirect(current_user, wizard_id, url)
end end
@ -209,9 +198,10 @@ after_initialize do
::UsersController.prepend CustomWizardUsersController ::UsersController.prepend CustomWizardUsersController
::Guardian.prepend CustomWizardGuardian ::Guardian.prepend CustomWizardGuardian
full_path = "#{Rails.root}/plugins/discourse-custom-wizard/assets/stylesheets/wizard/wizard_custom.scss" full_path =
"#{Rails.root}/plugins/discourse-custom-wizard/assets/stylesheets/wizard/wizard_custom.scss"
if Stylesheet::Importer.respond_to?(:plugin_assets) if Stylesheet::Importer.respond_to?(:plugin_assets)
Stylesheet::Importer.plugin_assets['wizard_custom'] = Set[full_path] Stylesheet::Importer.plugin_assets["wizard_custom"] = Set[full_path]
else else
# legacy method, Discourse 2.7.0.beta5 and below # legacy method, Discourse 2.7.0.beta5 and below
DiscoursePluginRegistry.register_asset(full_path, {}, "wizard_custom") DiscoursePluginRegistry.register_asset(full_path, {}, "wizard_custom")
@ -225,9 +215,11 @@ after_initialize do
add_model_callback(klass, :after_initialize) do add_model_callback(klass, :after_initialize) do
if CustomWizard::CustomField.enabled? if CustomWizard::CustomField.enabled?
CustomWizard::CustomField.list_by(:klass, klass.to_s).each do |field| CustomWizard::CustomField
class_constant.register_custom_field_type(field[:name], field[:type].to_sym) .list_by(:klass, klass.to_s)
end .each do |field|
class_constant.register_custom_field_type(field[:name], field[:type].to_sym)
end
end end
end end
@ -247,11 +239,11 @@ after_initialize do
on(:before_create_topic) do |topic_params, user| on(:before_create_topic) do |topic_params, user|
category = topic_params.category category = topic_params.category
wizard_submission_id = topic_params.custom_fields&.[]('wizard_submission_id') wizard_submission_id = topic_params.custom_fields&.[]("wizard_submission_id")
if category&.custom_fields&.[]('create_topic_wizard').present? && wizard_submission_id.blank? if category&.custom_fields&.[]("create_topic_wizard").present? && wizard_submission_id.blank?
raise Discourse::InvalidParameters.new( raise Discourse::InvalidParameters.new(
I18n.t('wizard.error_messages.wizard_replacing_composer') I18n.t("wizard.error_messages.wizard_replacing_composer"),
) )
end end
end end
end end

Datei anzeigen

@ -1,10 +1,26 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::Action do describe CustomWizard::Action do
fab!(:user) { Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com", trust_level: TrustLevel[2]) } fab!(:user) do
fab!(:user1) { Fabricate(:user, name: "Angus One", username: 'angus1', email: "angus_one@email.com", trust_level: TrustLevel[2]) } Fabricate(
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') } :user,
fab!(:tag) { Fabricate(:tag, name: 'tag1') } name: "Angus",
username: "angus",
email: "angus@email.com",
trust_level: TrustLevel[2],
)
end
fab!(:user1) do
Fabricate(
:user,
name: "Angus One",
username: "angus1",
email: "angus_one@email.com",
trust_level: TrustLevel[2],
)
end
fab!(:category) { Fabricate(:category, name: "cat1", slug: "cat-slug") }
fab!(:tag) { Fabricate(:tag, name: "tag1") }
fab!(:group) fab!(:group)
let(:wizard_template) { get_wizard_fixture("wizard") } let(:wizard_template) { get_wizard_fixture("wizard") }
@ -24,137 +40,129 @@ describe CustomWizard::Action do
def update_template(template) def update_template(template)
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find("super_mega_fun_wizard")
end end
let(:create_topic) { let(:create_topic) do
JSON.parse( JSON.parse(
File.open( File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/create_topic.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/create_topic.json",
).read ).read,
) )
} end
let(:custom_field_json) { let(:custom_field_json) do
JSON.parse(File.open( JSON.parse(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" File.open(
).read) "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json",
} ).read,
)
end
before do before do
Group.refresh_automatic_group!(:trust_level_2) Group.refresh_automatic_group!(:trust_level_2)
update_template(wizard_template) update_template(wizard_template)
end end
describe '#create_topic' do describe "#create_topic" do
it "works" do it "works" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater( wizard.create_updater(
wizard.steps.first.id, wizard.steps.first.id,
step_1_field_1: "Topic Title", step_1_field_1: "Topic Title",
step_1_field_2: "topic body" step_1_field_2: "topic body",
).update ).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
step_3_field_3: category.id
).update
topic = Topic.where( topic = Topic.where(title: "Topic Title", category_id: category.id)
title: "Topic Title",
category_id: category.id
)
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect(Post.where( expect(Post.where(topic_id: topic.pluck(:id), raw: "topic body").exists?).to eq(true)
topic_id: topic.pluck(:id),
raw: "topic body"
).exists?).to eq(true)
end end
it "fails silently without basic topic inputs" do it "fails silently without basic topic inputs" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater( wizard.create_updater(wizard.steps.first.id, step_1_field_2: "topic body").update
wizard.steps.first.id,
step_1_field_2: "topic body"
).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
updater = wizard.create_updater(wizard.steps.last.id, {}) updater = wizard.create_updater(wizard.steps.last.id, {})
updater.update updater.update
expect(updater.success?).to eq(true) expect(updater.success?).to eq(true)
expect(CustomWizard::UserHistory.where( expect(
actor_id: user.id, CustomWizard::UserHistory.where(
context: "super_mega_fun_wizard", actor_id: user.id,
subject: "step_3" context: "super_mega_fun_wizard",
).exists?).to eq(true) subject: "step_3",
expect(Post.where( ).exists?,
raw: "topic body" ).to eq(true)
).exists?).to eq(false) expect(Post.where(raw: "topic body").exists?).to eq(false)
end end
it "adds custom fields" do it "adds custom fields" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps.first.id, wizard.create_updater(
wizard.steps.first.id,
step_1_field_1: "Topic Title", step_1_field_1: "Topic Title",
step_1_field_2: "topic body" step_1_field_2: "topic body",
).update ).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
step_3_field_3: category.id
).update
topic = Topic.where( topic = Topic.where(title: "Topic Title", category_id: category.id).first
title: "Topic Title", topic_custom_field =
category_id: category.id TopicCustomField.where(
).first name: "topic_field",
topic_custom_field = TopicCustomField.where( value: "Topic custom field value",
name: "topic_field", topic_id: topic.id,
value: "Topic custom field value", )
topic_id: topic.id topic_json_custom_field =
) TopicCustomField.where(
topic_json_custom_field = TopicCustomField.where(" "
name = 'topic_json_field' AND name = 'topic_json_field' AND
(value::json->>'key_1') = 'Key 1 value' AND (value::json->>'key_1') = 'Key 1 value' AND
(value::json->>'key_2') = 'Key 2 value' AND (value::json->>'key_2') = 'Key 2 value' AND
topic_id = #{topic.id}" topic_id = #{topic.id}",
) )
post_custom_field = PostCustomField.where( post_custom_field =
name: "post_field", PostCustomField.where(
value: "Post custom field value", name: "post_field",
post_id: topic.first_post.id value: "Post custom field value",
) post_id: topic.first_post.id,
)
expect(topic_custom_field.exists?).to eq(true) expect(topic_custom_field.exists?).to eq(true)
expect(topic_json_custom_field.exists?).to eq(true) expect(topic_json_custom_field.exists?).to eq(true)
expect(post_custom_field.exists?).to eq(true) expect(post_custom_field.exists?).to eq(true)
end end
it "adds registered custom fields" do it "adds registered custom fields" do
custom_field = custom_field_json['custom_fields'][0] custom_field = custom_field_json["custom_fields"][0]
custom_field_name = custom_field["name"] custom_field_name = custom_field["name"]
custom_field_value = "Custom value" custom_field_value = "Custom value"
CustomWizard::CustomField.new(nil, custom_field).save CustomWizard::CustomField.new(nil, custom_field).save
create_topic["custom_fields"] = [ create_topic["custom_fields"] = [
{ {
"type": "association", type: "association",
"pairs": [ pairs: [
{ {
"index": 0, index: 0,
"key": custom_field_name, key: custom_field_name,
"key_type": "custom_field", key_type: "custom_field",
"value": custom_field_value, value: custom_field_value,
"value_type": "text", value_type: "text",
"connector": "association" connector: "association",
} },
] ],
} },
] ]
wizard = CustomWizard::Wizard.new(@template, user) wizard = CustomWizard::Wizard.new(@template, user)
action = CustomWizard::Action.new( action =
wizard: wizard, CustomWizard::Action.new(
action: create_topic.with_indifferent_access, wizard: wizard,
submission: wizard.current_submission action: create_topic.with_indifferent_access,
) submission: wizard.current_submission,
)
action.perform action.perform
expect(action.result.success?).to eq(true) expect(action.result.success?).to eq(true)
@ -163,14 +171,7 @@ describe CustomWizard::Action do
it "allows poster to be set" do it "allows poster to be set" do
wizard_template[:actions][0]["poster"] = [ wizard_template[:actions][0]["poster"] = [
{ { type: "assignment", output_type: "user", output_connector: "set", output: ["angus1"] },
"type": "assignment",
"output_type": "user",
"output_connector": "set",
"output": [
"angus1"
]
}
] ]
update_template(wizard_template) update_template(wizard_template)
@ -178,45 +179,39 @@ describe CustomWizard::Action do
wizard.create_updater( wizard.create_updater(
wizard.steps.first.id, wizard.steps.first.id,
step_1_field_1: "Topic Title", step_1_field_1: "Topic Title",
step_1_field_2: "topic body" step_1_field_2: "topic body",
).update ).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
step_3_field_3: category.id
).update
topic = Topic.where( topic = Topic.where(title: "Topic Title", category_id: category.id)
title: "Topic Title",
category_id: category.id
)
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
post = Post.find_by( post = Post.find_by(topic_id: topic.pluck(:id), raw: "topic body")
topic_id: topic.pluck(:id),
raw: "topic body"
)
expect(post.present?).to eq(true) expect(post.present?).to eq(true)
expect(post.user.username).to eq('angus1') expect(post.user.username).to eq("angus1")
end end
end end
it 'updates a profile' do it "updates a profile" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
upload = Upload.create!( upload =
url: '/images/image.png', Upload.create!(
original_filename: 'image.png', url: "/images/image.png",
filesize: 100, original_filename: "image.png",
user_id: -1, filesize: 100,
) user_id: -1,
)
steps = wizard.steps steps = wizard.steps
wizard.create_updater(steps[0].id, {}).update wizard.create_updater(steps[0].id, {}).update
wizard.create_updater(steps[1].id, wizard.create_updater(
step_2_field_7: upload.as_json(only: [:id, :url, :user_id]) steps[1].id,
step_2_field_7: upload.as_json(only: %i[id url user_id]),
).update ).update
expect(user.profile_background_upload.id).to eq(upload.id) expect(user.profile_background_upload.id).to eq(upload.id)
end end
context "open composer" do context "open composer" do
it 'works' do it "works" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
@ -224,33 +219,34 @@ describe CustomWizard::Action do
updater.update updater.update
expect(updater.result[:redirect_on_next]).to eq( expect(updater.result[:redirect_on_next]).to eq(
"/new-topic?title=Title%20of%20the%20composer%20topic&body=I%20am%20interpolating%20some%20user%20fields%20Angus%20angus%20angus%40email.com&tags=tag1" "/new-topic?title=Title%20of%20the%20composer%20topic&body=I%20am%20interpolating%20some%20user%20fields%20Angus%20angus%20angus%40email.com&tags=tag1",
) )
end end
it 'encodes special characters in the title and body' do it "encodes special characters in the title and body" do
open_composer['title'][0]['output'] = "Title that's special $".dup open_composer["title"][0]["output"] = "Title that's special $".dup
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 =
wizard: wizard, CustomWizard::Action.new(
action: open_composer, wizard: wizard,
submission: wizard.current_submission action: open_composer,
) submission: wizard.current_submission,
)
action.perform action.perform
expect(action.result.success?).to eq(true) expect(action.result.success?).to eq(true)
decoded_output = CGI.parse(URI.parse(action.result.output).query) decoded_output = CGI.parse(URI.parse(action.result.output).query)
expect(decoded_output['title'][0]).to eq("Title that's special $") expect(decoded_output["title"][0]).to eq("Title that's special $")
expect(decoded_output['body'][0]).to eq("Body & more body & more body") expect(decoded_output["body"][0]).to eq("Body & more body & more body")
end end
end end
context "route to action" do context "route to action" do
it 're-routes a user' do it "re-routes a user" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
updater = wizard.create_updater(wizard.steps.last.id, {}) updater = wizard.create_updater(wizard.steps.last.id, {})
updater.update updater.update
@ -274,7 +270,7 @@ describe CustomWizard::Action do
Jobs.run_immediately! Jobs.run_immediately!
end end
it 'watches tags' do it "watches tags" do
watch_tags[:tags][0][:output] = tag.name watch_tags[:tags][0][:output] = tag.name
wizard_template[:actions] << watch_tags wizard_template[:actions] << watch_tags
update_template(wizard_template) update_template(wizard_template)
@ -282,13 +278,10 @@ describe CustomWizard::Action do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
expect(TagUser.where( expect(TagUser.where(tag_id: tag.id, user_id: user.id).first.notification_level).to eq(2)
tag_id: tag.id,
user_id: user.id
).first.notification_level).to eq(2)
end end
it 'watches categories' do it "watches categories" do
watch_categories[:categories][0][:output] = category.id watch_categories[:categories][0][:output] = category.id
wizard_template[:actions] << watch_categories wizard_template[:actions] << watch_categories
update_template(wizard_template) update_template(wizard_template)
@ -296,34 +289,27 @@ describe CustomWizard::Action do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
expect(CategoryUser.where( expect(
category_id: category.id, CategoryUser.where(category_id: category.id, user_id: user.id).first.notification_level,
user_id: user.id ).to eq(2)
).first.notification_level).to eq(2)
end end
it '#send_message' do it "#send_message" do
Jobs.run_immediately! Jobs.run_immediately!
target_user = Fabricate(:user) target_user = Fabricate(:user)
send_message['recipient'][0]['output'][0] = target_user.username send_message["recipient"][0]["output"][0] = target_user.username
wizard_template['actions'] << send_message wizard_template["actions"] << send_message
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, {}).update wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
topic = Topic.where( topic = Topic.where(archetype: Archetype.private_message, title: "Message title")
archetype: Archetype.private_message,
title: "Message title"
)
post = Post.where( post = Post.where(topic_id: topic.pluck(:id), raw: "I will interpolate some wizard fields")
topic_id: topic.pluck(:id),
raw: "I will interpolate some wizard fields"
)
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect(topic.first.topic_allowed_users.first.user.username).to eq(target_user.username) expect(topic.first.topic_allowed_users.first.user.username).to eq(target_user.username)
@ -331,7 +317,7 @@ describe CustomWizard::Action do
expect(target_user.reload.notifications.count).to eq(1) expect(target_user.reload.notifications.count).to eq(1)
end end
it '#send_message allows using multiple targets' do it "#send_message allows using multiple targets" do
Jobs.run_immediately! Jobs.run_immediately!
user1 = Fabricate(:user) user1 = Fabricate(:user)
@ -339,13 +325,13 @@ describe CustomWizard::Action do
group1 = Fabricate(:group) group1 = Fabricate(:group)
group2 = Fabricate(:group) group2 = Fabricate(:group)
send_message_multi['recipient'][0]['output'] = [ send_message_multi["recipient"][0]["output"] = [
user1.username, user1.username,
user2.username, user2.username,
group1.name, group1.name,
group2.name group2.name,
] ]
wizard_template['actions'] << send_message_multi wizard_template["actions"] << send_message_multi
update_template(wizard_template) update_template(wizard_template)
update_template(wizard_template) update_template(wizard_template)
@ -353,18 +339,15 @@ describe CustomWizard::Action do
wizard.create_updater(wizard.steps[0].id, {}).update wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
topic = Topic.where( topic = Topic.where(archetype: Archetype.private_message, title: "Multiple Recipients title")
archetype: Archetype.private_message,
title: "Multiple Recipients title"
)
post = Post.where( post = Post.where(topic_id: topic.pluck(:id), raw: "I will interpolate some wizard fields")
topic_id: topic.pluck(:id),
raw: "I will interpolate some wizard fields"
)
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect(topic.first.all_allowed_users.map(&:username)).to include(user1.username, user2.username) expect(topic.first.all_allowed_users.map(&:username)).to include(
user1.username,
user2.username,
)
expect(topic.first.allowed_groups.map(&:name)).to include(group1.name, group2.name) expect(topic.first.allowed_groups.map(&:name)).to include(group1.name, group2.name)
expect(post.exists?).to eq(true) expect(post.exists?).to eq(true)
expect(user1.reload.notifications.count).to eq(1) expect(user1.reload.notifications.count).to eq(1)
@ -378,27 +361,27 @@ describe CustomWizard::Action do
wizard_template["permitted"] = guests_permitted["permitted"] wizard_template["permitted"] = guests_permitted["permitted"]
wizard_template[:steps][0][:fields] << { wizard_template[:steps][0][:fields] << {
"id": "step_1_field_5", id: "step_1_field_5",
"label": "Guest Email", label: "Guest Email",
"type": "text", type: "text",
"min_length": "3", min_length: "3",
}.as_json }.as_json
create_topic["run_after"] = "step_3" create_topic["run_after"] = "step_3"
create_topic["guest_email"] = [ create_topic["guest_email"] = [
{ {
"type": "assignment", type: "assignment",
"output": "step_1_field_5", output: "step_1_field_5",
"output_type": "wizard_field", output_type: "wizard_field",
"output_connector": "set" output_connector: "set",
} },
] ]
create_topic["category"] = [ create_topic["category"] = [
{ {
"type": "assignment", type: "assignment",
"output": "step_3_field_3", output: "step_3_field_3",
"output_type": "wizard_field", output_type: "wizard_field",
"output_connector": "set" output_connector: "set",
} },
] ]
wizard_template.delete("actions") wizard_template.delete("actions")
wizard_template[:actions] = [create_topic] wizard_template[:actions] = [create_topic]
@ -407,47 +390,39 @@ describe CustomWizard::Action do
end end
it "creates a staged guest poster if guest_email is set" do it "creates a staged guest poster if guest_email is set" do
wizard = CustomWizard::Builder.new( wizard =
@template[:id], CustomWizard::Builder.new(
nil, @template[:id],
CustomWizard::Wizard.generate_guest_id nil,
).build CustomWizard::Wizard.generate_guest_id,
wizard.create_updater( ).build
wizard.steps.first.id, wizard.create_updater(wizard.steps.first.id, step_1_field_5: "guest@email.com").update
step_1_field_5: "guest@email.com"
).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
step_3_field_3: category.id
).update
topic = Topic.where(category_id: category.id).first topic = Topic.where(category_id: category.id).first
expect(topic.present?).to eq(true) expect(topic.present?).to eq(true)
expect(topic.posts.first.user.staged).to eq(true) expect(topic.posts.first.user.staged).to eq(true)
expect(topic.posts.first.user.primary_email.email).to eq('guest@email.com') expect(topic.posts.first.user.primary_email.email).to eq("guest@email.com")
end end
it "returns an existing user with the same email" do it "returns an existing user with the same email" do
existing = Fabricate(:user, email: 'guest@email.com') existing = Fabricate(:user, email: "guest@email.com")
wizard = CustomWizard::Builder.new( wizard =
@template[:id], CustomWizard::Builder.new(
nil, @template[:id],
CustomWizard::Wizard.generate_guest_id nil,
).build CustomWizard::Wizard.generate_guest_id,
wizard.create_updater( ).build
wizard.steps.first.id, wizard.create_updater(wizard.steps.first.id, step_1_field_5: "guest@email.com").update
step_1_field_5: "guest@email.com"
).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
step_3_field_3: category.id
).update
topic = Topic.where(category_id: category.id).first topic = Topic.where(category_id: category.id).first
expect(topic.present?).to eq(true) expect(topic.present?).to eq(true)
expect(topic.posts.first.user.staged).to eq(false) expect(topic.posts.first.user.staged).to eq(false)
expect(topic.posts.first.user.primary_email.email).to eq('guest@email.com') expect(topic.posts.first.user.primary_email.email).to eq("guest@email.com")
end end
end end
@ -455,10 +430,15 @@ describe CustomWizard::Action do
it "works" do it "works" do
wizard_template["permitted"] = guests_permitted["permitted"] wizard_template["permitted"] = guests_permitted["permitted"]
wizard_template.delete("actions") wizard_template.delete("actions")
wizard_template['actions'] = [send_message] wizard_template["actions"] = [send_message]
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(wizard_template["id"], nil, CustomWizard::Wizard.generate_guest_id).build wizard =
CustomWizard::Builder.new(
wizard_template["id"],
nil,
CustomWizard::Wizard.generate_guest_id,
).build
wizard.create_updater(wizard.steps[0].id, {}).update wizard.create_updater(wizard.steps[0].id, {}).update
updater = wizard.create_updater(wizard.steps[1].id, {}) updater = wizard.create_updater(wizard.steps[1].id, {})
updater.update updater.update
@ -468,7 +448,9 @@ describe CustomWizard::Action do
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect(topic.first.topic_allowed_users.first.user.username).to eq(user1.username) expect(topic.first.topic_allowed_users.first.user.username).to eq(user1.username)
expect(topic.first.topic_allowed_users.second.user.username).to eq(Discourse.system_user.username) expect(topic.first.topic_allowed_users.second.user.username).to eq(
Discourse.system_user.username,
)
expect(post.exists?).to eq(true) expect(post.exists?).to eq(true)
end end
@ -480,19 +462,24 @@ describe CustomWizard::Action do
send_message["recipient"] = [ send_message["recipient"] = [
{ {
"type": "assignment", type: "assignment",
"output": "step_1_field_1", output: "step_1_field_1",
"output_type": "wizard_field", output_type: "wizard_field",
"output_connector": "set" output_connector: "set",
} },
] ]
wizard_template['actions'] = [send_message] wizard_template["actions"] = [send_message]
update_template(wizard_template) update_template(wizard_template)
NotificationEmailer.expects(:process_notification).once NotificationEmailer.expects(:process_notification).once
wizard = CustomWizard::Builder.new(wizard_template["id"], nil, CustomWizard::Wizard.generate_guest_id).build wizard =
CustomWizard::Builder.new(
wizard_template["id"],
nil,
CustomWizard::Wizard.generate_guest_id,
).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "guest@email.com").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "guest@email.com").update
updater = wizard.create_updater(wizard.steps[1].id, {}) updater = wizard.create_updater(wizard.steps[1].id, {})
updater.update updater.update
@ -502,8 +489,12 @@ describe CustomWizard::Action do
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect(topic.first.topic_allowed_users.first.user.staged).to eq(true) expect(topic.first.topic_allowed_users.first.user.staged).to eq(true)
expect(topic.first.topic_allowed_users.first.user.primary_email.email).to eq('guest@email.com') expect(topic.first.topic_allowed_users.first.user.primary_email.email).to eq(
expect(topic.first.topic_allowed_users.second.user.username).to eq(Discourse.system_user.username) "guest@email.com",
)
expect(topic.first.topic_allowed_users.second.user.username).to eq(
Discourse.system_user.username,
)
expect(post.exists?).to eq(true) expect(post.exists?).to eq(true)
end end
end end
@ -511,149 +502,146 @@ describe CustomWizard::Action do
end end
context "business subscription actions" do context "business subscription actions" do
before do before { enable_subscription("business") }
enable_subscription("business")
end
it '#create_category' do it "#create_category" do
wizard_template['actions'] << create_category wizard_template["actions"] << create_category
wizard_template['actions'] << create_group wizard_template["actions"] << create_group
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
expect(Category.where(id: wizard.current_submission.fields['action_8']).exists?).to eq(true) expect(Category.where(id: wizard.current_submission.fields["action_8"]).exists?).to eq(true)
end end
it '#create_group' do it "#create_group" do
wizard_template['actions'] << create_group wizard_template["actions"] << create_group
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
group_id = Group.where(name: wizard.current_submission.fields['action_9']).first.id group_id = Group.where(name: wizard.current_submission.fields["action_9"]).first.id
user_id = User.find_by(username: wizard_template['actions'][4]['usernames'][0]["output"][0]).id user_id =
User.find_by(username: wizard_template["actions"][4]["usernames"][0]["output"][0]).id
expect(Group.where(name: wizard.current_submission.fields['action_9']).exists?).to eq(true) expect(Group.where(name: wizard.current_submission.fields["action_9"]).exists?).to eq(true)
expect(GroupUser.where(group_id: group_id, user_id: user_id).exists?).to eq(true) expect(GroupUser.where(group_id: group_id, user_id: user_id).exists?).to eq(true)
end end
it '#create_group completes successfully when user included in usernames does not exist but excludes users who do not exist and includes warning in log' do it "#create_group completes successfully when user included in usernames does not exist but excludes users who do not exist and includes warning in log" do
wizard_template['actions'] << create_group_with_nonexistent_user wizard_template["actions"] << create_group_with_nonexistent_user
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
group_id = Group.where(name: wizard.current_submission.fields['action_9']).first.id group_id = Group.where(name: wizard.current_submission.fields["action_9"]).first.id
expect(CustomWizard::Log.list_query.all.last.value.include? "some users were not found").to eq(true) expect(
expect(Group.where(name: wizard.current_submission.fields['action_9']).exists?).to eq(true) CustomWizard::Log.list_query.all.last.value.include? "some users were not found"
).to eq(true)
expect(Group.where(name: wizard.current_submission.fields["action_9"]).exists?).to eq(true)
expect(GroupUser.where(group_id: group_id).count).to eq(1) expect(GroupUser.where(group_id: group_id).count).to eq(1)
end end
it '#add_to_group' do it "#add_to_group" do
wizard_template['actions'] << create_group wizard_template["actions"] << create_group
wizard_template['actions'] << add_to_group wizard_template["actions"] << add_to_group
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
step_id = wizard.steps[0].id step_id = wizard.steps[0].id
updater = wizard.create_updater(step_id, step_1_field_1: "Text input").update updater = wizard.create_updater(step_id, step_1_field_1: "Text input").update
group = Group.find_by(name: wizard.current_submission.fields['action_9']) group = Group.find_by(name: wizard.current_submission.fields["action_9"])
expect(group.users.first.username).to eq('angus') expect(group.users.first.username).to eq("angus")
end end
it '#send_to_api successful' do it "#send_to_api successful" do
stub_request(:put, "https://myexternalapi.com/update"). stub_request(:put, "https://myexternalapi.com/update").with(
with(
body: "some_body", body: "some_body",
headers: { headers: {
'Host' => 'myexternalapi.com' "Host" => "myexternalapi.com",
}). },
to_return(status: 200, body: "success", headers: {}) ).to_return(status: 200, body: "success", headers: {})
new_api = CustomWizard::Api.new("my_api") new_api = CustomWizard::Api.new("my_api")
CustomWizard::Api.set("my_api", title: "Mocked external api") CustomWizard::Api.set("my_api", title: "Mocked external api")
CustomWizard::Api::Authorization.set("my_api", api_test_no_authorization) CustomWizard::Api::Authorization.set("my_api", api_test_no_authorization)
CustomWizard::Api::Endpoint.new("my_api") CustomWizard::Api::Endpoint.new("my_api")
CustomWizard::Api::Endpoint.set("my_api", api_test_endpoint) CustomWizard::Api::Endpoint.set("my_api", api_test_endpoint)
endpoint_id = CustomWizard::Api::Endpoint.list("my_api").first.id endpoint_id = CustomWizard::Api::Endpoint.list("my_api").first.id
result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body") result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body")
log_entry = CustomWizard::Api::LogEntry.list("my_api").first log_entry = CustomWizard::Api::LogEntry.list("my_api").first
expect(result).to eq('success') expect(result).to eq("success")
expect(log_entry.status).to eq('SUCCESS') expect(log_entry.status).to eq("SUCCESS")
end end
it '#send_to_api failure' do it "#send_to_api failure" do
stub_request(:put, "https://myexternalapi.com/update"). stub_request(:put, "https://myexternalapi.com/update").with(
with(
body: "some_body", body: "some_body",
headers: { headers: {
'Host' => 'myexternalapi.com' "Host" => "myexternalapi.com",
}). },
to_return(status: 500, body: "failure", headers: {}) ).to_return(status: 500, body: "failure", headers: {})
new_api = CustomWizard::Api.new("my_api") new_api = CustomWizard::Api.new("my_api")
CustomWizard::Api.set("my_api", title: "Mocked external api") CustomWizard::Api.set("my_api", title: "Mocked external api")
CustomWizard::Api::Authorization.set("my_api", api_test_no_authorization) CustomWizard::Api::Authorization.set("my_api", api_test_no_authorization)
CustomWizard::Api::Endpoint.new("my_api") CustomWizard::Api::Endpoint.new("my_api")
CustomWizard::Api::Endpoint.set("my_api", api_test_endpoint) CustomWizard::Api::Endpoint.set("my_api", api_test_endpoint)
endpoint_id = CustomWizard::Api::Endpoint.list("my_api").first.id endpoint_id = CustomWizard::Api::Endpoint.list("my_api").first.id
result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body") result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body")
log_entry = CustomWizard::Api::LogEntry.list("my_api").first log_entry = CustomWizard::Api::LogEntry.list("my_api").first
expect(result).to eq({ error: "API request failed" }) expect(result).to eq({ error: "API request failed" })
expect(log_entry.status).to eq('FAIL') expect(log_entry.status).to eq("FAIL")
end end
end end
it 'registers callbacks' do it "registers callbacks" do
described_class.register_callback(:before_create_topic) do |params, wizard, action, submission| described_class.register_callback(:before_create_topic) do |params, wizard, action, submission|
params[:topic_opts][:custom_fields]["topic_custom_field"] = true params[:topic_opts][:custom_fields]["topic_custom_field"] = true
params params
end end
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
action = CustomWizard::Action.new( action =
wizard: wizard, CustomWizard::Action.new(
action: create_topic.with_indifferent_access, wizard: wizard,
submission: wizard.current_submission action: create_topic.with_indifferent_access,
) submission: wizard.current_submission,
)
action.perform action.perform
expect(action.result.success?).to eq(true) expect(action.result.success?).to eq(true)
expect(Topic.find(action.result.output).custom_fields["topic_custom_field"]).to eq("t") expect(Topic.find(action.result.output).custom_fields["topic_custom_field"]).to eq("t")
end end
context 'creating a topic when there are multiple actions' do context "creating a topic when there are multiple actions" do
it 'works' do it "works" do
wizard_template['actions'] << create_topic wizard_template["actions"] << create_topic
wizard_template['actions'] << send_message wizard_template["actions"] << send_message
update_template(wizard_template) update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater( wizard.create_updater(
wizard.steps.first.id, wizard.steps.first.id,
step_1_field_1: 'Topic Title', step_1_field_1: "Topic Title",
step_1_field_2: 'topic body' step_1_field_2: "topic body",
).update ).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id) wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
.update
wizard.create_updater(wizard.steps[0].id, {}).update wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
topic = Topic.where(title: 'Topic Title', category_id: category.id) topic = Topic.where(title: "Topic Title", category_id: category.id)
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect( expect(Post.where(topic_id: topic.pluck(:id), raw: "topic body").exists?).to eq(true)
Post.where(topic_id: topic.pluck(:id), raw: 'topic body').exists?
).to eq(true)
end end
end end
end end

Datei anzeigen

@ -1,18 +1,13 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::Builder do describe CustomWizard::Builder do
fab!(:trusted_user) { fab!(:trusted_user) do
Fabricate( Fabricate(:user, username: "angus", email: "angus@email.com", trust_level: TrustLevel[3])
:user, end
username: 'angus', fab!(:user)
email: "angus@email.com", fab!(:category1) { Fabricate(:category, name: "cat1") }
trust_level: TrustLevel[3] fab!(:category2) { Fabricate(:category, name: "cat2") }
) fab!(:group)
}
fab!(:user) { Fabricate(:user) }
fab!(:category1) { Fabricate(:category, name: 'cat1') }
fab!(:category2) { Fabricate(:category, name: 'cat2') }
fab!(:group) { Fabricate(:group) }
let(:wizard_template) { get_wizard_fixture("wizard") } let(:wizard_template) { get_wizard_fixture("wizard") }
let(:required_data_json) { get_wizard_fixture("step/required_data") } let(:required_data_json) { get_wizard_fixture("step/required_data") }
@ -20,36 +15,30 @@ describe CustomWizard::Builder do
let(:permitted_param_json) { get_wizard_fixture("step/permitted_params") } let(:permitted_param_json) { get_wizard_fixture("step/permitted_params") }
let(:user_condition_json) { get_wizard_fixture("condition/user_condition") } let(:user_condition_json) { get_wizard_fixture("condition/user_condition") }
let(:boolean_field_condition_json) { let(:boolean_field_condition_json) do
JSON.parse( JSON.parse(
File.open( File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/boolean_field_condition.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/boolean_field_condition.json",
).read ).read,
) )
} end
before do before do
Group.refresh_automatic_group!(:trust_level_3) Group.refresh_automatic_group!(:trust_level_3)
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find("super_mega_fun_wizard")
end end
context 'disabled' do context "disabled" do
before do before { SiteSetting.custom_wizard_enabled = false }
SiteSetting.custom_wizard_enabled = false
end
it "returns nil" do it "returns nil" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build).to eq(nil)
CustomWizard::Builder.new(@template[:id], user).build
).to eq(nil)
end end
end end
context 'enabled' do context "enabled" do
before do before { SiteSetting.custom_wizard_enabled = true }
SiteSetting.custom_wizard_enabled = true
end
it "returns wizard metadata" do it "returns wizard metadata" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
@ -59,10 +48,7 @@ describe CustomWizard::Builder do
end end
it "returns steps" do it "returns steps" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(3)
CustomWizard::Builder.new(@template[:id], user).build
.steps.length
).to eq(3)
end end
context "with multiple submissions disabled" do context "with multiple submissions disabled" do
@ -71,27 +57,21 @@ describe CustomWizard::Builder do
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'returns steps if user has not completed it' do it "returns steps if user has not completed it" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(3)
CustomWizard::Builder.new(@template[:id], user).build
.steps.length
).to eq(3)
end end
it 'returns no steps if user has completed it' do it "returns no steps if user has completed it" do
@template[:steps].each do |step| @template[:steps].each do |step|
CustomWizard::UserHistory.create!( CustomWizard::UserHistory.create!(
action: CustomWizard::UserHistory.actions[:step], action: CustomWizard::UserHistory.actions[:step],
actor_id: user.id, actor_id: user.id,
context: @template[:id], context: @template[:id],
subject: step[:id] subject: step[:id],
) )
end end
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(0)
CustomWizard::Builder.new(@template[:id], user).build
.steps.length
).to eq(0)
end end
end end
@ -102,81 +82,56 @@ describe CustomWizard::Builder do
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'is not permitted if user is not in permitted group' do it "is not permitted if user is not in permitted group" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.permitted?).to eq(false)
CustomWizard::Builder.new(@template[:id], user).build
.permitted?
).to eq(false)
end end
it 'user cannot access if not permitted' do it "user cannot access if not permitted" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.can_access?).to eq(false)
CustomWizard::Builder.new(@template[:id], user).build
.can_access?
).to eq(false)
end end
it 'returns wizard metadata if user is not permitted' do it "returns wizard metadata if user is not permitted" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.name).to eq(
CustomWizard::Builder.new(@template[:id], user).build "Super Mega Fun Wizard",
.name )
).to eq("Super Mega Fun Wizard")
end end
it 'returns no steps if user is not permitted' do it "returns no steps if user is not permitted" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(0)
CustomWizard::Builder.new(@template[:id], user).build
.steps.length
).to eq(0)
end end
it 'is permitted if user is in permitted group' do it "is permitted if user is in permitted group" do
expect( expect(CustomWizard::Builder.new(@template[:id], trusted_user).build.permitted?).to eq(true)
CustomWizard::Builder.new(@template[:id], trusted_user).build
.permitted?
).to eq(true)
end end
it 'user can access if permitted' do it "user can access if permitted" do
expect( expect(CustomWizard::Builder.new(@template[:id], trusted_user).build.can_access?).to eq(
CustomWizard::Builder.new(@template[:id], trusted_user).build true,
.can_access? )
).to eq(true)
end end
it 'returns steps if user is permitted' do it "returns steps if user is permitted" do
expect( expect(CustomWizard::Builder.new(@template[:id], trusted_user).build.steps.length).to eq(3)
CustomWizard::Builder.new(@template[:id], trusted_user).build
.steps.length
).to eq(3)
end end
end end
it 'returns prefilled data' do it "returns prefilled data" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.first.value,
.steps.first ).to eq("I am prefilled")
.fields.first
.value
).to eq('I am prefilled')
end end
context "user has partially completed" do context "user has partially completed" do
before do before do
wizard = CustomWizard::Wizard.new(@template, user) wizard = CustomWizard::Wizard.new(@template, user)
data = { data = { step_1_field_1: "I am a user submission" }
step_1_field_1: 'I am a user submission'
}
CustomWizard::Submission.new(wizard, data).save CustomWizard::Submission.new(wizard, data).save
end end
it 'returns saved submissions' do it "returns saved submissions" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.first.value,
.steps.first ).to eq("I am a user submission")
.fields.first
.value
).to eq('I am a user submission')
end end
context "restart is enabled" do context "restart is enabled" do
@ -186,100 +141,87 @@ describe CustomWizard::Builder do
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'does not return saved submissions' do it "does not return saved submissions" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.first.value,
.steps.first ).to eq("I am prefilled")
.fields.first
.value
).to eq('I am prefilled')
end end
end end
end end
context 'building step' do context "building step" do
it 'returns step metadata' do it "returns step metadata" do
first_step = CustomWizard::Builder.new(@template[:id], user) first_step = CustomWizard::Builder.new(@template[:id], user).build(reset: true).steps.first
.build(reset: true)
.steps.first
expect(first_step.id).to eq("step_1") expect(first_step.id).to eq("step_1")
expect(first_step.title).to eq("Text") expect(first_step.title).to eq("Text")
expect(first_step.description).to eq("<p>Text inputs!</p>") expect(first_step.description).to eq("<p>Text inputs!</p>")
end end
context 'with required data' do context "with required data" do
before do before do
enable_subscription("standard") enable_subscription("standard")
@template[:steps][0][:required_data] = required_data_json['required_data'] @template[:steps][0][:required_data] = required_data_json["required_data"]
@template[:steps][0][:required_data_message] = required_data_json['required_data_message'] @template[:steps][0][:required_data_message] = required_data_json["required_data_message"]
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'is not permitted if required data is not present' do it "is not permitted if required data is not present" do
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.steps.first.permitted).to eq(
CustomWizard::Builder.new(@template[:id], user).build false,
.steps.first )
.permitted
).to eq(false)
end end
it 'it shows required data message' do it "it shows required data message" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build.steps.first.permitted_message,
.steps.first
.permitted_message
).to eq("Missing required data") ).to eq("Missing required data")
end end
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)
CustomWizard::Submission.new(wizard, step_1_field_1: "required").save CustomWizard::Submission.new(wizard, step_1_field_1: "required").save
expect( expect(CustomWizard::Builder.new(@template[:id], user).build.steps.first.permitted).to eq(
CustomWizard::Builder.new(@template[:id], user).build true,
.steps.first )
.permitted
).to eq(true)
end end
end end
context "with permitted params" do context "with permitted params" do
before do before do
enable_subscription("standard") enable_subscription("standard")
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params'] @template[:steps][0][:permitted_params] = permitted_param_json["permitted_params"]
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'saves permitted params' do it "saves permitted params" 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.fields["saved_param"]).to eq("param_value")
)
expect(wizard.current_submission.fields['saved_param']).to eq('param_value')
end end
end end
context "with condition" do context "with condition" do
before do before do
enable_subscription("standard") enable_subscription("standard")
@template[:steps][0][:condition] = user_condition_json['condition'] @template[:steps][0][:condition] = user_condition_json["condition"]
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it "adds step when condition is passed" do it "adds step when condition is passed" do
wizard = CustomWizard::Builder.new(@template[:id], trusted_user).build wizard = CustomWizard::Builder.new(@template[:id], trusted_user).build
expect(wizard.steps.first.id).to eq(@template[:steps][0]['id']) expect(wizard.steps.first.id).to eq(@template[:steps][0]["id"])
end end
it "does not add step when condition is not passed" do it "does not add step when condition is not passed" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
expect(wizard.steps.first.id).to eq(@template[:steps][1]['id']) expect(wizard.steps.first.id).to eq(@template[:steps][1]["id"])
end end
end end
end end
context 'building field' do context "building field" do
it 'returns field metadata' do it "returns field metadata" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
field = wizard.steps.first.fields.first field = wizard.steps.first.fields.first
@ -289,59 +231,56 @@ describe CustomWizard::Builder do
expect(field.min_length).to eq("3") expect(field.min_length).to eq("3")
end end
it 'returns all step fields' do it "returns all step fields" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user) CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.length,
.build
.steps.first
.fields.length
).to eq(@template[:steps][0][:fields].length) ).to eq(@template[:steps][0][:fields].length)
end end
context "with condition" do context "with condition" do
before do before do
enable_subscription("standard") enable_subscription("standard")
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition'] @template[:steps][0][:fields][0][:condition] = user_condition_json["condition"]
@template[:steps][2][:fields][0][:condition] = boolean_field_condition_json['condition'] @template[:steps][2][:fields][0][:condition] = boolean_field_condition_json["condition"]
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it "adds field when condition is passed" do it "adds field when condition is passed" do
wizard = CustomWizard::Builder.new(@template[:id], trusted_user).build wizard = CustomWizard::Builder.new(@template[:id], trusted_user).build
expect(wizard.steps.first.fields.first.id).to eq(@template[:steps][0][:fields][0]['id']) expect(wizard.steps.first.fields.first.id).to eq(@template[:steps][0][:fields][0]["id"])
end end
it "does not add field when condition is not passed" do it "does not add field when condition is not passed" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
expect(wizard.steps.first.fields.first.id).to eq(@template[:steps][0][:fields][1]['id']) expect(wizard.steps.first.fields.first.id).to eq(@template[:steps][0][:fields][1]["id"])
end end
it "works if a field condition uses 'is true/false'" do it "works if a field condition uses 'is true/false'" do
builder = CustomWizard::Builder.new(@template[:id], user) builder = CustomWizard::Builder.new(@template[:id], user)
wizard = builder.build wizard = builder.build
wizard.create_updater('step_2', step_2_field_5: 'true').update wizard.create_updater("step_2", step_2_field_5: "true").update
builder = CustomWizard::Builder.new(@template[:id], user) builder = CustomWizard::Builder.new(@template[:id], user)
wizard = builder.build wizard = builder.build
expect(wizard.steps.last.fields.last.id).to eq(@template[:steps][2][:fields][0]['id']) expect(wizard.steps.last.fields.last.id).to eq(@template[:steps][2][:fields][0]["id"])
end end
end end
end end
context 'on update' do context "on update" do
def perform_update(step_id, submission) def perform_update(step_id, submission)
updater = @wizard.create_updater(step_id, submission) updater = @wizard.create_updater(step_id, submission)
updater.update updater.update
updater updater
end end
it 'saves submissions' do it "saves submissions" do
@wizard = CustomWizard::Builder.new(@template[:id], user).build @wizard = CustomWizard::Builder.new(@template[:id], user).build
perform_update('step_1', step_1_field_1: 'Text input') perform_update("step_1", step_1_field_1: "Text input")
expect(@wizard.current_submission.fields['step_1_field_1']).to eq('Text input') expect(@wizard.current_submission.fields["step_1_field_1"]).to eq("Text input")
end end
context 'save submissions disabled' do context "save submissions disabled" do
before do before do
enable_subscription("standard") enable_subscription("standard")
@template[:save_submissions] = false @template[:save_submissions] = false
@ -350,7 +289,7 @@ describe CustomWizard::Builder do
end end
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.present?).to eq(false) expect(@wizard.current_submission.present?).to eq(false)
end end
end end

Datei anzeigen

@ -2,22 +2,20 @@
describe CustomWizard::Cache do describe CustomWizard::Cache do
it "writes and reads values to the cache" do it "writes and reads values to the cache" do
CustomWizard::Cache.new('list').write([1, 2, 3]) CustomWizard::Cache.new("list").write([1, 2, 3])
expect(CustomWizard::Cache.new('list').read).to eq([1, 2, 3]) expect(CustomWizard::Cache.new("list").read).to eq([1, 2, 3])
end end
it "deletes values from the cache" do it "deletes values from the cache" do
CustomWizard::Cache.new('list').delete CustomWizard::Cache.new("list").delete
expect(CustomWizard::Cache.new('list').read).to eq(nil) expect(CustomWizard::Cache.new("list").read).to eq(nil)
end end
describe "#wrap" do describe "#wrap" do
before do before { @raw = [1, 2, 3] }
@raw = [1, 2, 3]
end
def list def list
CustomWizard::Cache.wrap('list') { @raw } CustomWizard::Cache.wrap("list") { @raw }
end end
it "returns value from passed block" do it "returns value from passed block" do

Datei anzeigen

@ -2,224 +2,229 @@
describe CustomWizard::CustomField do describe CustomWizard::CustomField do
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
let(:custom_field_subscription_json) { get_wizard_fixture("custom_field/subscription_custom_fields") } let(:custom_field_subscription_json) do
get_wizard_fixture("custom_field/subscription_custom_fields")
before do
CustomWizard::CustomField.invalidate_cache
end end
before { CustomWizard::CustomField.invalidate_cache }
it "saves custom field records" do it "saves custom field records" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
expect(custom_field.save).to eq(true) expect(custom_field.save).to eq(true)
expect( expect(
PluginStoreRow.where(" PluginStoreRow.where(
"
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
key = '#{custom_field.name}' AND key = '#{custom_field.name}' AND
value::jsonb = '#{field_json.except('name').to_json}'::jsonb value::jsonb = '#{field_json.except("name").to_json}'::jsonb
",).exists? ",
).exists?,
).to eq(true) ).to eq(true)
end end
end end
it "updates existing custom field records" do it "updates existing custom field records" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
updated_field_json = custom_field_json['custom_fields'][0] updated_field_json = custom_field_json["custom_fields"][0]
updated_field_json['serializers'] = ["topic_view"] updated_field_json["serializers"] = ["topic_view"]
existing_field = CustomWizard::CustomField.find_by_name(updated_field_json["name"]) existing_field = CustomWizard::CustomField.find_by_name(updated_field_json["name"])
updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json) updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json)
expect(updated_field.save).to eq(true) expect(updated_field.save).to eq(true)
expect( expect(
PluginStoreRow.where(" PluginStoreRow.where(
"
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
key = '#{updated_field.name}' AND key = '#{updated_field.name}' AND
value::jsonb = '#{updated_field_json.except('name').to_json}'::jsonb value::jsonb = '#{updated_field_json.except("name").to_json}'::jsonb
",).exists? ",
).exists?,
).to eq(true) ).to eq(true)
end end
context "validation" do context "validation" do
it "does not save without required attributes" do it "does not save without required attributes" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json["custom_fields"].first
invalid_field_json['klass'] = nil invalid_field_json["klass"] = nil
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.required_attribute", attr: "klass") I18n.t("wizard.custom_field.error.required_attribute", attr: "klass"),
) )
expect( expect(
PluginStoreRow.where( PluginStoreRow.where(
plugin_name: CustomWizard::CustomField::NAMESPACE, plugin_name: CustomWizard::CustomField::NAMESPACE,
key: custom_field.name key: custom_field.name,
).exists? ).exists?,
).to eq(false) ).to eq(false)
end end
it "does save without optional attributes" do it "does save without optional attributes" do
field_json = custom_field_json['custom_fields'].first field_json = custom_field_json["custom_fields"].first
field_json['serializers'] = nil field_json["serializers"] = nil
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
expect(custom_field.save).to eq(true) expect(custom_field.save).to eq(true)
expect(custom_field.valid?).to eq(true) expect(custom_field.valid?).to eq(true)
expect( expect(
PluginStoreRow.where(" PluginStoreRow.where(
"
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
key = '#{custom_field.name}' AND key = '#{custom_field.name}' AND
value::jsonb = '#{field_json.except('name').to_json}'::jsonb value::jsonb = '#{field_json.except("name").to_json}'::jsonb
",).exists? ",
).exists?,
).to eq(true) ).to eq(true)
end end
it "does not save with an unsupported class" do it "does not save with an unsupported class" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json["custom_fields"].first
invalid_field_json['klass'] = 'user' invalid_field_json["klass"] = "user"
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.unsupported_class", class: "user") I18n.t("wizard.custom_field.error.unsupported_class", class: "user"),
) )
expect( expect(
PluginStoreRow.where( PluginStoreRow.where(
plugin_name: CustomWizard::CustomField::NAMESPACE, plugin_name: CustomWizard::CustomField::NAMESPACE,
key: custom_field.name key: custom_field.name,
).exists? ).exists?,
).to eq(false) ).to eq(false)
end end
it "does not save with an unsupported serializer" do it "does not save with an unsupported serializer" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json["custom_fields"].first
invalid_field_json['klass'] = 'post' invalid_field_json["klass"] = "post"
invalid_field_json['serializers'] = ['post', 'post_revision'] invalid_field_json["serializers"] = %w[post post_revision]
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.unsupported_serializers", I18n.t(
"wizard.custom_field.error.unsupported_serializers",
class: "post", class: "post",
serializers: "post_revision" serializers: "post_revision",
) ),
) )
expect( expect(
PluginStoreRow.where( PluginStoreRow.where(
plugin_name: CustomWizard::CustomField::NAMESPACE, plugin_name: CustomWizard::CustomField::NAMESPACE,
key: custom_field.name key: custom_field.name,
).exists? ).exists?,
).to eq(false) ).to eq(false)
end end
it "does not save with an unsupported type" do it "does not save with an unsupported type" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json["custom_fields"].first
invalid_field_json['type'] = 'bigint' invalid_field_json["type"] = "bigint"
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.unsupported_type", type: "bigint") I18n.t("wizard.custom_field.error.unsupported_type", type: "bigint"),
) )
expect( expect(
PluginStoreRow.where( PluginStoreRow.where(
plugin_name: CustomWizard::CustomField::NAMESPACE, plugin_name: CustomWizard::CustomField::NAMESPACE,
key: custom_field.name key: custom_field.name,
).exists? ).exists?,
).to eq(false) ).to eq(false)
end end
it "does not save with a short field name" do it "does not save with a short field name" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json["custom_fields"].first
invalid_field_json['name'] = 'cf' invalid_field_json["name"] = "cf"
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.name_too_short", name: "cf") I18n.t("wizard.custom_field.error.name_too_short", name: "cf"),
) )
expect( expect(
PluginStoreRow.where( PluginStoreRow.where(
plugin_name: CustomWizard::CustomField::NAMESPACE, plugin_name: CustomWizard::CustomField::NAMESPACE,
key: custom_field.name key: custom_field.name,
).exists? ).exists?,
).to eq(false) ).to eq(false)
end end
it "does not save with an existing name if new" do it "does not save with an existing name if new" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
first_field_json = custom_field_json['custom_fields'][0] first_field_json = custom_field_json["custom_fields"][0]
custom_field = CustomWizard::CustomField.new(nil, first_field_json) custom_field = CustomWizard::CustomField.new(nil, first_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.name_already_taken", name: "topic_field_1") I18n.t("wizard.custom_field.error.name_already_taken", name: "topic_field_1"),
) )
end end
it "does not save with an invalid name" do it "does not save with an invalid name" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json["custom_fields"].first
invalid_field_json['name'] = ["invalid_name"] invalid_field_json["name"] = ["invalid_name"]
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.name_invalid", name: ["invalid_name"]) I18n.t("wizard.custom_field.error.name_invalid", name: ["invalid_name"]),
) )
expect( expect(
PluginStoreRow.where( PluginStoreRow.where(
plugin_name: CustomWizard::CustomField::NAMESPACE, plugin_name: CustomWizard::CustomField::NAMESPACE,
key: custom_field.name key: custom_field.name,
).exists? ).exists?,
).to eq(false) ).to eq(false)
end end
it "does not save subscription field types without a subscription" do it "does not save subscription field types without a subscription" do
subscription_field_json = custom_field_subscription_json['custom_fields'].first subscription_field_json = custom_field_subscription_json["custom_fields"].first
custom_field = CustomWizard::CustomField.new(nil, subscription_field_json) custom_field = CustomWizard::CustomField.new(nil, subscription_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.subscription_type", type: "json") I18n.t("wizard.custom_field.error.subscription_type", type: "json"),
) )
end end
it "does not save subscription field classes without a subscription" do it "does not save subscription field classes without a subscription" do
subscription_field_json = custom_field_subscription_json['custom_fields'].second subscription_field_json = custom_field_subscription_json["custom_fields"].second
custom_field = CustomWizard::CustomField.new(nil, subscription_field_json) custom_field = CustomWizard::CustomField.new(nil, subscription_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.subscription_type", type: "category") I18n.t("wizard.custom_field.error.subscription_type", type: "category"),
) )
end end
context "with a subscription" do context "with a subscription" do
before do before { enable_subscription("business") }
enable_subscription("business")
end
it "saves subscription field types" do it "saves subscription field types" do
subscription_field_json = custom_field_subscription_json['custom_fields'].first subscription_field_json = custom_field_subscription_json["custom_fields"].first
custom_field = CustomWizard::CustomField.new(nil, subscription_field_json) custom_field = CustomWizard::CustomField.new(nil, subscription_field_json)
expect(custom_field.save).to eq(true) expect(custom_field.save).to eq(true)
@ -227,7 +232,7 @@ describe CustomWizard::CustomField do
end end
it "saves subscription field classes" do it "saves subscription field classes" do
subscription_field_json = custom_field_subscription_json['custom_fields'].second subscription_field_json = custom_field_subscription_json["custom_fields"].second
custom_field = CustomWizard::CustomField.new(nil, subscription_field_json) custom_field = CustomWizard::CustomField.new(nil, subscription_field_json)
expect(custom_field.save).to eq(true) expect(custom_field.save).to eq(true)
@ -238,7 +243,7 @@ describe CustomWizard::CustomField do
context "lists" do context "lists" do
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
end end
@ -248,15 +253,15 @@ describe CustomWizard::CustomField do
end end
it "saved custom field records by attribute value" do it "saved custom field records by attribute value" do
expect(CustomWizard::CustomField.list_by(:klass, 'topic').length).to eq(1) expect(CustomWizard::CustomField.list_by(:klass, "topic").length).to eq(1)
end end
it "saved custom field records by optional values" do it "saved custom field records by optional values" do
field_json = custom_field_json['custom_fields'].first field_json = custom_field_json["custom_fields"].first
field_json['serializers'] = nil field_json["serializers"] = nil
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
expect(CustomWizard::CustomField.list_by(:serializers, ['post']).length).to eq(0) expect(CustomWizard::CustomField.list_by(:serializers, ["post"]).length).to eq(0)
end end
it "custom field records added by other plugins " do it "custom field records added by other plugins " do
@ -269,7 +274,7 @@ describe CustomWizard::CustomField do
end end
it "is enabled if there are custom fields" do it "is enabled if there are custom fields" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
expect(CustomWizard::CustomField.enabled?).to eq(true) expect(CustomWizard::CustomField.enabled?).to eq(true)

Datei anzeigen

@ -5,12 +5,14 @@ describe CustomWizard::Field do
before do before do
CustomWizard::Field.register( CustomWizard::Field.register(
'location', "location",
'discourse-locations', "discourse-locations",
['components', 'helpers', 'lib', 'stylesheets', 'templates'], %w[components helpers lib stylesheets templates],
type_opts: { type_opts: {
prefill: { "coordinates": [35.3082, 149.1244] } prefill: {
} coordinates: [35.3082, 149.1244],
},
},
) )
end end
@ -31,14 +33,14 @@ describe CustomWizard::Field do
end end
it "allows custom field types to set default attributes" do it "allows custom field types to set default attributes" do
expect( expect(CustomWizard::Field.types[:location][:prefill]).to eq(
CustomWizard::Field.types[:location][:prefill] { coordinates: [35.3082, 149.1244] },
).to eq({ "coordinates": [35.3082, 149.1244] }) )
end end
it "registers custom field assets" do it "registers custom field assets" do
expect( expect(CustomWizard::Field.require_assets["discourse-locations"]).to eq(
CustomWizard::Field.require_assets['discourse-locations'] %w[components helpers lib stylesheets templates],
).to eq(['components', 'helpers', 'lib', 'stylesheets', 'templates']) )
end end
end end

Datei anzeigen

@ -2,32 +2,42 @@
describe CustomWizard::Log do describe CustomWizard::Log do
before do before do
CustomWizard::Log.create('first-test-wizard', 'perform_first_action', 'first_test_user', 'First log message', 5.minutes.ago) CustomWizard::Log.create(
CustomWizard::Log.create('second-test-wizard', 'perform_second_action', 'second_test_user', 'Second log message', 3.minutes.ago) "first-test-wizard",
CustomWizard::Log.create('third-test-wizard', 'perform_third_action', 'third_test_user', 'Third log message', 1.minutes.ago) "perform_first_action",
"first_test_user",
"First log message",
5.minutes.ago,
)
CustomWizard::Log.create(
"second-test-wizard",
"perform_second_action",
"second_test_user",
"Second log message",
3.minutes.ago,
)
CustomWizard::Log.create(
"third-test-wizard",
"perform_third_action",
"third_test_user",
"Third log message",
1.minutes.ago,
)
end end
it "creates logs" do it "creates logs" do
expect( expect(CustomWizard::Log.list.logs.length).to eq(3)
CustomWizard::Log.list.logs.length
).to eq(3)
end end
it "lists logs by time created" do it "lists logs by time created" do
expect( expect(CustomWizard::Log.list.logs.first.message).to eq("Third log message")
CustomWizard::Log.list.logs.first.message
).to eq("Third log message")
end end
it "paginates logs" do it "paginates logs" do
expect( expect(CustomWizard::Log.list(0, 2).logs.length).to eq(2)
CustomWizard::Log.list(0, 2).logs.length
).to eq(2)
end end
it "lists logs by wizard" do it "lists logs by wizard" do
expect( expect(CustomWizard::Log.list(0, 2, "third-test-wizard").logs.length).to eq(1)
CustomWizard::Log.list(0, 2, 'third-test-wizard').logs.length
).to eq(1)
end end
end end

Datei anzeigen

@ -1,429 +1,403 @@
# rubocop:disable Style/FrozenStringLiteralComment # rubocop:disable Style/FrozenStringLiteralComment
describe CustomWizard::Mapper do describe CustomWizard::Mapper do
fab!(:user1) { fab!(:user1) do
Fabricate(:user, Fabricate(
:user,
name: "Angus", name: "Angus",
username: "angus", username: "angus",
email: "angus@email.com", email: "angus@email.com",
trust_level: TrustLevel[3] trust_level: TrustLevel[3],
) )
} end
fab!(:user2) { fab!(:user2) do
Fabricate(:user, Fabricate(
:user,
name: "Patrick", name: "Patrick",
username: "patrick", username: "patrick",
email: "patrick@email2.com", email: "patrick@email2.com",
trust_level: TrustLevel[1] trust_level: TrustLevel[1],
) )
} end
fab!(:user_field) { fab!(:user_field) do
field = Fabricate(:user_field, field =
id: 3, Fabricate(
name: 'dropdown_field', :user_field,
description: 'field desc', id: 3,
field_type: 'dropdown', name: "dropdown_field",
user_field_options_attributes: [ description: "field desc",
{ value: "a" }, field_type: "dropdown",
{ value: "b" }, user_field_options_attributes: [{ value: "a" }, { value: "b" }, { value: "c" }],
{ value: "c" } )
] end
)
}
let(:inputs) { get_wizard_fixture("mapper/inputs") } let(:inputs) { get_wizard_fixture("mapper/inputs") }
let(:data) { get_wizard_fixture("mapper/data") } let(:data) { get_wizard_fixture("mapper/data") }
let(:template_params) { let(:template_params) { { "step_1_field_1" => "Hello" } }
{ let(:template_params_empty) do
"step_1_field_1" => "Hello" { "step_1_field_1" => nil, "step_1_field_2" => nil, "step_1_field_3" => "" }
} end
} let(:template_params_non_empty) do
let(:template_params_empty) { { "step_1_field_1" => nil, "step_1_field_2" => "", "step_1_field_3" => "Value" }
{ end
"step_1_field_1" => nil, let(:template_params_multiple_non_empty) do
"step_1_field_2" => nil, { "step_1_field_1" => nil, "step_1_field_2" => "Value1", "step_1_field_3" => "Value" }
"step_1_field_3" => "" end
} let(:template_params_object) { { step_1_field_1: get_wizard_fixture("field/upload") } }
} let(:template_params_object_array) do
let(:template_params_non_empty) { { "step_1_field_1" => [{ text: "Hello" }, { text: "World" }] }
{ end
"step_1_field_1" => nil,
"step_1_field_2" => "",
"step_1_field_3" => "Value"
}
}
let(:template_params_multiple_non_empty) {
{
"step_1_field_1" => nil,
"step_1_field_2" => "Value1",
"step_1_field_3" => "Value"
}
}
let(:template_params_object) {
{
"step_1_field_1": get_wizard_fixture("field/upload")
}
}
let(:template_params_object_array) {
{
"step_1_field_1" => [{ text: "Hello" }, { text: "World" }]
}
}
def create_template_mapper(data, user) def create_template_mapper(data, user)
CustomWizard::Mapper.new( CustomWizard::Mapper.new(data: data, user: user)
data: data,
user: user
)
end end
it "maps values" do it "maps values" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['assignment'], CustomWizard::Mapper.new(inputs: inputs["assignment"], data: data, user: user1).perform,
data: data, ).to eq([13])
user: user1
).perform).to eq([13])
end end
it "maps associations" do it "maps associations" do
association = CustomWizard::Mapper.new( association =
inputs: inputs['association'], CustomWizard::Mapper.new(inputs: inputs["association"], data: data, user: user1).perform
data: data,
user: user1
).perform
expect(association.length).to eq(3) expect(association.length).to eq(3)
expect(association.first[:value]).to eq("Choice 1") expect(association.first[:value]).to eq("Choice 1")
end end
context "conditional mapping" do context "conditional mapping" do
it "maps when the condition is met" do it "maps when the condition is met" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['conditional'], CustomWizard::Mapper.new(inputs: inputs["conditional"], data: data, user: user1).perform,
data: data, ).to eq("true")
user: user1
).perform).to eq("true")
end end
it "does not map when the condition is not met" do it "does not map when the condition is not met" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['conditional'], CustomWizard::Mapper.new(inputs: inputs["conditional"], data: data, user: user2).perform,
data: data, ).to eq(nil)
user: user2
).perform).to eq(nil)
end end
it "maps when multiple conditions are met" do it "maps when multiple conditions are met" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['conditional_multiple_pairs'], CustomWizard::Mapper.new(
data: data, inputs: inputs["conditional_multiple_pairs"],
user: user1 data: data,
).perform).to eq("true") user: user1,
).perform,
).to eq("true")
end end
it "does not map when one of multiple conditions are not met" do it "does not map when one of multiple conditions are not met" do
user1.email = "angus@other-email.com" user1.email = "angus@other-email.com"
user1.save user1.save
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['conditional_multiple_pairs'], CustomWizard::Mapper.new(
data: data, inputs: inputs["conditional_multiple_pairs"],
user: user1 data: data,
).perform).to eq(nil) user: user1,
).perform,
).to eq(nil)
end end
end end
context "conditional validation" do context "conditional validation" do
it "validates valid data" do it "validates valid data" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['validation'], CustomWizard::Mapper.new(inputs: inputs["validation"], data: data, user: user1).perform,
data: data, ).to eq(true)
user: user1
).perform).to eq(true)
end end
it "does not validate invalid data" do it "does not validate invalid data" do
data["input_2"] = "value 3" data["input_2"] = "value 3"
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['validation'], CustomWizard::Mapper.new(inputs: inputs["validation"], data: data, user: user1).perform,
data: data, ).to eq(false)
user: user1
).perform).to eq(false)
end end
context "using or condition" do context "using or condition" do
it "validates the data when all of the conditions are met" do it "validates the data when all of the conditions are met" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['validation_multiple_pairs'], CustomWizard::Mapper
data: data, .new(
user: user1, inputs: inputs["validation_multiple_pairs"],
opts: { data: data,
multiple: true user: user1,
} opts: {
).perform.any?).to eq(true) multiple: true,
},
)
.perform
.any?,
).to eq(true)
end end
it "validates the data when one of the conditions are met" do it "validates the data when one of the conditions are met" do
custom_data = data.dup custom_data = data.dup
custom_data['input_1'] = 'value 3' custom_data["input_1"] = "value 3"
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['validation_multiple_pairs'], CustomWizard::Mapper
data: custom_data, .new(
user: user1, inputs: inputs["validation_multiple_pairs"],
opts: { data: custom_data,
multiple: true user: user1,
} opts: {
).perform.any?).to eq(true) multiple: true,
},
)
.perform
.any?,
).to eq(true)
end end
it "doesn't validate the data when none of the conditions are met" do it "doesn't validate the data when none of the conditions are met" do
custom_data = data.dup custom_data = data.dup
custom_data['input_1'] = 'value 3' custom_data["input_1"] = "value 3"
custom_data['input_2'] = 'value 4' custom_data["input_2"] = "value 4"
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['validation_multiple_pairs'], CustomWizard::Mapper
data: custom_data, .new(
user: user1, inputs: inputs["validation_multiple_pairs"],
opts: { data: custom_data,
multiple: true user: user1,
} opts: {
).perform.any?).to eq(false) multiple: true,
},
)
.perform
.any?,
).to eq(false)
end end
end end
end end
it "maps text fields" do it "maps text fields" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['assignment_text'], CustomWizard::Mapper.new(inputs: inputs["assignment_text"], data: data, user: user1).perform,
data: data, ).to eq("Value")
user: user1
).perform).to eq("Value")
end end
it "maps user fields" do it "maps user fields" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['assignment_user_field'], CustomWizard::Mapper.new(
data: data, inputs: inputs["assignment_user_field"],
user: user1 data: data,
).perform).to eq("Angus") user: user1,
).perform,
).to eq("Angus")
end end
it "maps user field options" do it "maps user field options" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['assignment_user_field_options'], CustomWizard::Mapper.new(
data: data, inputs: inputs["assignment_user_field_options"],
user: user1 data: data,
).perform).to eq(["a", "b", "c"]) user: user1,
).perform,
).to eq(%w[a b c])
end end
it "maps wizard fields" do it "maps wizard fields" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['assignment_wizard_field'], CustomWizard::Mapper.new(
data: data, inputs: inputs["assignment_wizard_field"],
user: user1 data: data,
).perform).to eq("value 1") user: user1,
).perform,
).to eq("value 1")
end end
it "maps wizard actions" do it "maps wizard actions" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['assignment_wizard_action'], CustomWizard::Mapper.new(
data: data, inputs: inputs["assignment_wizard_action"],
user: user1 data: data,
).perform).to eq("value 2") user: user1,
).perform,
).to eq("value 2")
end end
context "interpolates" do context "interpolates" do
it "user fields" do it "user fields" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['interpolate_user_field'], CustomWizard::Mapper.new(
data: data, inputs: inputs["interpolate_user_field"],
user: user1 data: data,
).perform).to eq("Name: Angus") user: user1,
).perform,
).to eq("Name: Angus")
end end
it "user emails" do it "user emails" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['interpolate_user_email'], CustomWizard::Mapper.new(
data: data, inputs: inputs["interpolate_user_email"],
user: user1 data: data,
).perform).to eq("Email: angus@email.com") user: user1,
).perform,
).to eq("Email: angus@email.com")
end end
it "user options" do it "user options" do
user1.user_option.update_columns(email_level: UserOption.email_level_types[:never]) user1.user_option.update_columns(email_level: UserOption.email_level_types[:never])
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['interpolate_user_option'], CustomWizard::Mapper.new(
data: data, inputs: inputs["interpolate_user_option"],
user: user1 data: data,
).perform).to eq("Email Level: #{UserOption.email_level_types[:never]}") user: user1,
).perform,
).to eq("Email Level: #{UserOption.email_level_types[:never]}")
end end
it "date" do it "date" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['interpolate_timestamp'], CustomWizard::Mapper.new(
data: data, inputs: inputs["interpolate_timestamp"],
user: user1 data: data,
).perform).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}") user: user1,
).perform,
).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}")
end end
it "avatar" do it "avatar" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['interpolate_avatar'], CustomWizard::Mapper.new(
data: data, inputs: inputs["interpolate_avatar"],
user: user1 data: data,
).perform).to eq("Avatar: ![avatar](#{user1.small_avatar_url})") user: user1,
).perform,
).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
end end
it "avatar with invalid size" do it "avatar with invalid size" do
avatar_inputs = inputs['interpolate_avatar'].dup avatar_inputs = inputs["interpolate_avatar"].dup
avatar_inputs[0]["output"] = "Avatar: ![avatar](u{avatar.345})" avatar_inputs[0]["output"] = "Avatar: ![avatar](u{avatar.345})"
expect(CustomWizard::Mapper.new( expect(
inputs: avatar_inputs, CustomWizard::Mapper.new(inputs: avatar_inputs, data: data, user: user1).perform,
data: data, ).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
user: user1
).perform).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
end end
it "avatar with valid size" do it "avatar with valid size" do
avatar_inputs = inputs['interpolate_avatar'].dup avatar_inputs = inputs["interpolate_avatar"].dup
avatar_inputs[0]["output"] = "Avatar: ![avatar](u{avatar.144})" avatar_inputs[0]["output"] = "Avatar: ![avatar](u{avatar.144})"
expect(CustomWizard::Mapper.new( expect(
inputs: avatar_inputs, CustomWizard::Mapper.new(inputs: avatar_inputs, data: data, user: user1).perform,
data: data, ).to eq("Avatar: ![avatar](#{user1.avatar_template_url.gsub("{size}", "144")})")
user: user1
).perform).to eq("Avatar: ![avatar](#{user1.avatar_template_url.gsub("{size}", "144")})")
end end
end end
it "handles not equal pairs" do it "handles not equal pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['not_equals_pair'], CustomWizard::Mapper.new(inputs: inputs["not_equals_pair"], data: data, user: user1).perform,
data: data, ).to eq(true)
user: user1 expect(
).perform).to eq(true) CustomWizard::Mapper.new(inputs: inputs["not_equals_pair"], data: data, user: user2).perform,
expect(CustomWizard::Mapper.new( ).to eq(false)
inputs: inputs['not_equals_pair'],
data: data,
user: user2
).perform).to eq(false)
end end
it "handles greater than pairs" do it "handles greater than pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['greater_than_pair'], CustomWizard::Mapper.new(
data: data, inputs: inputs["greater_than_pair"],
user: user1 data: data,
).perform).to eq(true) user: user1,
expect(CustomWizard::Mapper.new( ).perform,
inputs: inputs['greater_than_pair'], ).to eq(true)
data: data, expect(
user: user2 CustomWizard::Mapper.new(
).perform).to eq(false) inputs: inputs["greater_than_pair"],
data: data,
user: user2,
).perform,
).to eq(false)
end end
it "handles less than pairs" do it "handles less than pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['less_than_pair'], CustomWizard::Mapper.new(inputs: inputs["less_than_pair"], data: data, user: user1).perform,
data: data, ).to eq(false)
user: user1 expect(
).perform).to eq(false) CustomWizard::Mapper.new(inputs: inputs["less_than_pair"], data: data, user: user2).perform,
expect(CustomWizard::Mapper.new( ).to eq(true)
inputs: inputs['less_than_pair'],
data: data,
user: user2
).perform).to eq(true)
end end
it "handles greater than or equal pairs" do it "handles greater than or equal pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['greater_than_or_equal_pair'], CustomWizard::Mapper.new(
data: data, inputs: inputs["greater_than_or_equal_pair"],
user: user1 data: data,
).perform).to eq(true) user: user1,
expect(CustomWizard::Mapper.new( ).perform,
inputs: inputs['greater_than_or_equal_pair'], ).to eq(true)
data: data, expect(
user: user2 CustomWizard::Mapper.new(
).perform).to eq(true) inputs: inputs["greater_than_or_equal_pair"],
data: data,
user: user2,
).perform,
).to eq(true)
end end
it "handles less than or equal pairs" do it "handles less than or equal pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['less_than_or_equal_pair'], CustomWizard::Mapper.new(
data: data, inputs: inputs["less_than_or_equal_pair"],
user: user1 data: data,
).perform).to eq(true) user: user1,
expect(CustomWizard::Mapper.new( ).perform,
inputs: inputs['less_than_or_equal_pair'], ).to eq(true)
data: data, expect(
user: user2 CustomWizard::Mapper.new(
).perform).to eq(true) inputs: inputs["less_than_or_equal_pair"],
data: data,
user: user2,
).perform,
).to eq(true)
end end
it "handles regex pairs" do it "handles regex pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['regex_pair'], CustomWizard::Mapper.new(inputs: inputs["regex_pair"], data: data, user: user1).perform,
data: data, ).to eq(true)
user: user1 expect(
).perform).to eq(true) CustomWizard::Mapper.new(inputs: inputs["regex_pair"], data: data, user: user2).perform,
expect(CustomWizard::Mapper.new( ).to eq(false)
inputs: inputs['regex_pair'],
data: data,
user: user2
).perform).to eq(false)
end end
it "handles shorthand pairs" do it "handles shorthand pairs" do
expect(CustomWizard::Mapper.new( expect(
inputs: inputs['shorthand_pair'], CustomWizard::Mapper.new(inputs: inputs["shorthand_pair"], data: data, user: user1).perform,
data: data, ).to eq(false)
user: user1
).perform).to eq(false)
end end
context "output templating" do context "output templating" do
it "passes the correct values to the template" do it "passes the correct values to the template" do
template = "w{step_1_field_1}" template = "w{step_1_field_1}"
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params["step_1_field_1"]) expect(result).to eq(template_params["step_1_field_1"])
end end
it "does not require a subscription" do it "does not require a subscription" do
template = '{{ "w{step_1_field_1}" | size }}' template = '{{ "w{step_1_field_1}" | size }}'
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq("5") expect(result).to eq("5")
end end
context "with a subscription" do context "with a subscription" do
before do before { enable_subscription("standard") }
enable_subscription("standard")
end
it "treats replaced values as string literals" do it "treats replaced values as string literals" do
template = '{{ "w{step_1_field_1}" | size }}' template = '{{ "w{step_1_field_1}" | size }}'
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params["step_1_field_1"].size.to_s) expect(result).to eq(template_params["step_1_field_1"].size.to_s)
end end
@ -436,26 +410,16 @@ describe CustomWizard::Mapper do
{%-endif-%} {%-endif-%}
LIQUID LIQUID
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq("Correct") expect(result).to eq("Correct")
end end
it "can access data passed to render method as variable" do it "can access data passed to render method as variable" do
template = "{{step_1_field_1.size}}" template = "{{step_1_field_1.size}}"
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params["step_1_field_1"].size.to_s) expect(result).to eq(template_params["step_1_field_1"].size.to_s)
end end
@ -464,10 +428,7 @@ describe CustomWizard::Mapper do
{{ "w{step_1_field_1}" | size}} {{ "w{step_1_field_1}" | size}}
LIQUID LIQUID
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result = mapper.interpolate(template.dup, template: false)
template.dup,
template: false,
)
expect(result).to eq(template) expect(result).to eq(template)
end end
@ -480,11 +441,7 @@ describe CustomWizard::Mapper do
{%-endif-%} {%-endif-%}
LIQUID LIQUID
mapper = create_template_mapper(template_params_object, user1) mapper = create_template_mapper(template_params_object, user1)
result = mapper.interpolate( result = mapper.interpolate(template.dup, template: true, wizard: true)
template.dup,
template: true,
wizard: true
)
expect(result).to eq("Correct") expect(result).to eq("Correct")
end end
@ -497,11 +454,7 @@ describe CustomWizard::Mapper do
{%-endif-%} {%-endif-%}
LIQUID LIQUID
mapper = create_template_mapper(template_params_object, user1) mapper = create_template_mapper(template_params_object, user1)
result = mapper.interpolate( result = mapper.interpolate(template.dup, template: true, wizard: true)
template.dup,
template: true,
wizard: true
)
expect(result).to eq("Incorrect") expect(result).to eq("Incorrect")
end end
@ -509,15 +462,10 @@ describe CustomWizard::Mapper do
template = <<-LIQUID.strip template = <<-LIQUID.strip
{% for object in step_1_field_1 %}{{object.text}} {% endfor %} {% for object in step_1_field_1 %}{{object.text}} {% endfor %}
LIQUID LIQUID
mapper = create_template_mapper(template_params_object_array, user1) mapper = create_template_mapper(template_params_object_array, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true, expect(result).to eq("Hello World ")
user: true,
wizard: true,
value: true
)
expect(result).to eq("Hello World ")
end end
context "custom filter: 'first_non_empty'" do context "custom filter: 'first_non_empty'" do
@ -527,13 +475,8 @@ describe CustomWizard::Mapper do
{{ entry }} {{ entry }}
LIQUID LIQUID
mapper = create_template_mapper(template_params_non_empty, user1) mapper = create_template_mapper(template_params_non_empty, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params_non_empty["step_1_field_3"]) expect(result).to eq(template_params_non_empty["step_1_field_3"])
end end
@ -543,13 +486,8 @@ describe CustomWizard::Mapper do
{{ entry }} {{ entry }}
LIQUID LIQUID
mapper = create_template_mapper(template_params_multiple_non_empty, user1) mapper = create_template_mapper(template_params_multiple_non_empty, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params_multiple_non_empty["step_1_field_2"]) expect(result).to eq(template_params_multiple_non_empty["step_1_field_2"])
end end
@ -561,13 +499,8 @@ describe CustomWizard::Mapper do
{%- endif -%} {%- endif -%}
LIQUID LIQUID
mapper = create_template_mapper(template_params_empty, user1) mapper = create_template_mapper(template_params_empty, user1)
result = mapper.interpolate( result =
template.dup, mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq("") expect(result).to eq("")
end end
end end

Datei anzeigen

@ -1,12 +1,14 @@
# frozen_string_literal: true # frozen_string_literal: true
describe ::CustomWizard::RealtimeValidation::SimilarTopics do describe ::CustomWizard::RealtimeValidation::SimilarTopics do
let(:post) { create_post(title: "matching similar topic") } let(:post) { create_post(title: "matching similar topic") }
let(:topic) { post.topic } let(:topic) { post.topic }
let(:category) { Fabricate(:category) } let(:category) { Fabricate(:category) }
let(:cat_post) { create_post(title: "matching similar topic slightly different", category: category) } let(:cat_post) do
let(:cat_topic) { cat_post.topic } create_post(title: "matching similar topic slightly different", category: category)
end
let(:cat_topic) { cat_post.topic }
let(:user) { cat_post.user } let(:user) { cat_post.user }
before do before do

Datei anzeigen

@ -4,9 +4,7 @@ describe CustomWizard::Step do
let(:step_hash) { get_wizard_fixture("step/step") } let(:step_hash) { get_wizard_fixture("step/step") }
let(:field_hash) { get_wizard_fixture("field/field") } let(:field_hash) { get_wizard_fixture("field/field") }
before do before { @step = CustomWizard::Step.new(step_hash[:id]) }
@step = CustomWizard::Step.new(step_hash[:id])
end
it "adds fields" do it "adds fields" do
@step.add_field(field_hash) @step.add_field(field_hash)

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::Submission do describe CustomWizard::Submission do
fab!(:user) { Fabricate(:user) } fab!(:user)
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
let(:template_json) { get_wizard_fixture("wizard") } let(:template_json) { get_wizard_fixture("wizard") }
let(:guest_id) { CustomWizard::Wizard.generate_guest_id } let(:guest_id) { CustomWizard::Wizard.generate_guest_id }
@ -13,9 +13,7 @@ describe CustomWizard::Submission do
end end
it "saves a user's submission" do it "saves a user's submission" do
expect( expect(described_class.get(@wizard).fields["step_1_field_1"]).to eq("I am user submission")
described_class.get(@wizard).fields["step_1_field_1"]
).to eq("I am user submission")
end end
it "saves a guest's submission" do it "saves a guest's submission" do
@ -23,9 +21,7 @@ describe CustomWizard::Submission do
@wizard = CustomWizard::Wizard.create(template_json["id"], nil, guest_id) @wizard = CustomWizard::Wizard.create(template_json["id"], nil, guest_id)
described_class.new(@wizard, step_1_field_1: "I am guest submission").save described_class.new(@wizard, step_1_field_1: "I am guest submission").save
expect( expect(described_class.get(@wizard).fields["step_1_field_1"]).to eq("I am guest submission")
described_class.get(@wizard).fields["step_1_field_1"]
).to eq("I am guest submission")
end end
describe "#list" do describe "#list" do
@ -41,7 +37,11 @@ describe CustomWizard::Submission do
@count = CustomWizard::Submission::PAGE_LIMIT + 20 @count = CustomWizard::Submission::PAGE_LIMIT + 20
@count.times do |index| @count.times do |index|
described_class.new(@wizard, step_1_field_1: "I am user submission #{index + 1}", submitted_at: Time.now + (index + 1).minutes).save described_class.new(
@wizard,
step_1_field_1: "I am user submission #{index + 1}",
submitted_at: Time.now + (index + 1).minutes,
).save
end end
described_class.new(@wizard2, step_1_field_1: "I am another user's submission").save described_class.new(@wizard2, step_1_field_1: "I am another user's submission").save
described_class.new(@wizard3, step_1_field_1: "I am a user submission on another wizard").save described_class.new(@wizard3, step_1_field_1: "I am a user submission on another wizard").save
@ -59,11 +59,15 @@ describe CustomWizard::Submission do
it "paginates submission lists" do it "paginates submission lists" do
@wizard.user = nil @wizard.user = nil
expect(described_class.list(@wizard, page: 1).submissions.size).to eq((@count + 2) - CustomWizard::Submission::PAGE_LIMIT) expect(described_class.list(@wizard, page: 1).submissions.size).to eq(
(@count + 2) - CustomWizard::Submission::PAGE_LIMIT,
)
end end
it "orders submissions by submitted_at" do it "orders submissions by submitted_at" do
expect(described_class.list(@wizard).submissions.first.submitted_at.to_datetime.change(usec: 0)).to eq((Time.now + @count.minutes).change(usec: 0)) expect(
described_class.list(@wizard).submissions.first.submitted_at.to_datetime.change(usec: 0),
).to eq((Time.now + @count.minutes).change(usec: 0))
end end
end end
@ -83,9 +87,7 @@ describe CustomWizard::Submission do
described_class.new(@wizard, step_1_field_1: "I am the second submission").save described_class.new(@wizard, step_1_field_1: "I am the second submission").save
described_class.new(@wizard, step_1_field_1: "I am the third submission").save described_class.new(@wizard, step_1_field_1: "I am the third submission").save
sub_data = PluginStore.get("#{@wizard.id}_submissions", @wizard.user.id) sub_data = PluginStore.get("#{@wizard.id}_submissions", @wizard.user.id)
sub_data.each do |sub| sub_data.each { |sub| sub["updated_at"] = nil }
sub['updated_at'] = nil
end
PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, sub_data) PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, sub_data)
builder = CustomWizard::Builder.new(@wizard.id, @wizard.user) builder = CustomWizard::Builder.new(@wizard.id, @wizard.user)
builder.build builder.build
@ -101,7 +103,7 @@ describe CustomWizard::Submission do
freeze_time Time.now + 2 freeze_time Time.now + 2
described_class.new(@wizard, step_1_field_1: "I am the third submission").save described_class.new(@wizard, step_1_field_1: "I am the third submission").save
sub_data = PluginStore.get("#{@wizard.id}_submissions", @wizard.user.id) sub_data = PluginStore.get("#{@wizard.id}_submissions", @wizard.user.id)
sub_data[0]['updated_at'] = nil sub_data[0]["updated_at"] = nil
PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, sub_data) PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, sub_data)
builder = CustomWizard::Builder.new(@wizard.id, @wizard.user) builder = CustomWizard::Builder.new(@wizard.id, @wizard.user)

Datei anzeigen

@ -5,19 +5,17 @@ describe CustomWizard::Subscription do
let!(:business_product_id) { SecureRandom.hex(8) } let!(:business_product_id) { SecureRandom.hex(8) }
let!(:standard_product_id) { SecureRandom.hex(8) } let!(:standard_product_id) { SecureRandom.hex(8) }
let!(:community_product_id) { SecureRandom.hex(8) } let!(:community_product_id) { SecureRandom.hex(8) }
let!(:product_slugs) { let!(:product_slugs) do
{ {
"#{business_product_id}" => "business", "#{business_product_id}" => "business",
"#{standard_product_id}" => "standard", "#{standard_product_id}" => "standard",
"#{community_product_id}" => "community" "#{community_product_id}" => "community",
} }
} end
context "with subscription client gem mocked out" do context "with subscription client gem mocked out" do
context "without a subscription" do context "without a subscription" do
before do before { DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(nil) }
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(nil)
end
it "has none type" do it "has none type" do
expect(described_class.type).to eq(:none) expect(described_class.type).to eq(:none)
@ -33,31 +31,43 @@ describe CustomWizard::Subscription do
end end
context "with subscriptions" do context "with subscriptions" do
def get_subscription_result(product_ids) def get_subscription_result(product_ids)
result = DiscourseSubscriptionClient::Subscriptions::Result.new result = DiscourseSubscriptionClient::Subscriptions::Result.new
result.supplier = SubscriptionClientSupplier.new(products: product_slugs) result.supplier = SubscriptionClientSupplier.new(products: product_slugs)
result.resource = SubscriptionClientResource.new result.resource = SubscriptionClientResource.new
result.subscriptions = product_ids.map { |product_id| ::SubscriptionClientSubscription.new(product_id: product_id) } result.subscriptions =
product_ids.map do |product_id|
::SubscriptionClientSubscription.new(product_id: product_id)
end
result.products = product_slugs result.products = product_slugs
result result
end end
let!(:business_subscription_result) { get_subscription_result([business_product_id]) } let!(:business_subscription_result) { get_subscription_result([business_product_id]) }
let!(:standard_subscription_result) { get_subscription_result([standard_product_id]) } let!(:standard_subscription_result) { get_subscription_result([standard_product_id]) }
let!(:community_subscription_result) { get_subscription_result([community_product_id]) } let!(:community_subscription_result) { get_subscription_result([community_product_id]) }
let!(:multiple_subscription_result) { get_subscription_result([community_product_id, business_product_id]) } let!(:multiple_subscription_result) do
get_subscription_result([community_product_id, business_product_id])
end
it "handles mapped values" do it "handles mapped values" do
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(standard_subscription_result) DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(standard_subscription_result)
expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(true) expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(
true,
)
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(community_subscription_result) DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(false) community_subscription_result,
)
expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(
false,
)
end end
context "with a standard subscription" do context "with a standard subscription" do
before do before do
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(standard_subscription_result) DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
standard_subscription_result,
)
end end
it "detects standard type" do it "detects standard type" do
@ -65,17 +75,19 @@ describe CustomWizard::Subscription do
end end
it "standard features are included" do it "standard features are included" do
expect(described_class.includes?(:wizard, :type, 'send_message')).to eq(true) expect(described_class.includes?(:wizard, :type, "send_message")).to eq(true)
end end
it "business features are not included" do it "business features are not included" do
expect(described_class.includes?(:action, :type, 'create_category')).to eq(false) expect(described_class.includes?(:action, :type, "create_category")).to eq(false)
end end
end end
context "with a business subscription" do context "with a business subscription" do
before do before do
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(business_subscription_result) DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
business_subscription_result,
)
end end
it "detects business type" do it "detects business type" do
@ -83,13 +95,15 @@ describe CustomWizard::Subscription do
end end
it "business features are included" do it "business features are included" do
expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) expect(described_class.includes?(:action, :type, "create_category")).to eq(true)
end end
end end
context "with a community subscription" do context "with a community subscription" do
before do before do
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(community_subscription_result) DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
community_subscription_result,
)
end end
it "detects community type" do it "detects community type" do
@ -97,13 +111,15 @@ describe CustomWizard::Subscription do
end end
it "community features are included" do it "community features are included" do
expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) expect(described_class.includes?(:action, :type, "create_category")).to eq(true)
end end
end end
context "with multiple subscriptions" do context "with multiple subscriptions" do
before do before do
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(multiple_subscription_result) DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
multiple_subscription_result,
)
end end
it "detects correct type in hierarchy" do it "detects correct type in hierarchy" do
@ -114,22 +130,16 @@ describe CustomWizard::Subscription do
end end
context "with environment variable" do context "with environment variable" do
before do before { ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = "standard" }
ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = "standard"
end
after do after { ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = nil }
ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = nil
end
it "enables the relevant subscription" do it "enables the relevant subscription" do
expect(described_class.type).to eq(:standard) expect(described_class.type).to eq(:standard)
end end
context "with a subscription" do context "with a subscription" do
before do before { enable_subscription("business") }
enable_subscription("business")
end
it "respects the subscription" do it "respects the subscription" do
expect(described_class.type).to eq(:business) expect(described_class.type).to eq(:business)

Datei anzeigen

@ -1,152 +1,133 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::Template do describe CustomWizard::Template do
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:template_json) { get_wizard_fixture("wizard") } let(:template_json) { get_wizard_fixture("wizard") }
let(:permitted_json) { get_wizard_fixture("wizard/permitted") } let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
fab!(:upload) { Fabricate(:upload) } fab!(:upload)
before do before { CustomWizard::Template.save(template_json, skip_jobs: true) }
CustomWizard::Template.save(template_json, skip_jobs: true)
end
it "saves wizard templates" do it "saves wizard templates" do
expect( expect(
PluginStoreRow.exists?( PluginStoreRow.exists?(plugin_name: "custom_wizard", key: "super_mega_fun_wizard"),
plugin_name: 'custom_wizard',
key: 'super_mega_fun_wizard'
)
).to eq(true) ).to eq(true)
end end
it "finds wizard templates" do it "finds wizard templates" do
expect( expect(CustomWizard::Template.find("super_mega_fun_wizard")["id"]).to eq(
CustomWizard::Template.find('super_mega_fun_wizard')['id'] "super_mega_fun_wizard",
).to eq('super_mega_fun_wizard') )
end end
it "removes wizard templates" do it "removes wizard templates" do
CustomWizard::Template.remove('super_mega_fun_wizard') CustomWizard::Template.remove("super_mega_fun_wizard")
expect( expect(CustomWizard::Template.find("super_mega_fun_wizard")).to eq(nil)
CustomWizard::Template.find('super_mega_fun_wizard')
).to eq(nil)
end end
it "removes user wizard redirects if template is removed" do it "removes user wizard redirects if template is removed" do
user.custom_fields['redirect_to_wizard'] = 'super_mega_fun_wizard' user.custom_fields["redirect_to_wizard"] = "super_mega_fun_wizard"
user.save_custom_fields(true) user.save_custom_fields(true)
CustomWizard::Template.remove('super_mega_fun_wizard') CustomWizard::Template.remove("super_mega_fun_wizard")
expect(user.reload.custom_fields['redirect_to_wizard']).to eq(nil) expect(user.reload.custom_fields["redirect_to_wizard"]).to eq(nil)
end end
it "checks for wizard template existence" do it "checks for wizard template existence" do
expect( expect(CustomWizard::Template.exists?("super_mega_fun_wizard")).to eq(true)
CustomWizard::Template.exists?('super_mega_fun_wizard')
).to eq(true)
end end
context "upload references" do context "upload references" do
it "are added if a wizard has a step banner" do it "are added if a wizard has a step banner" do
template_json['steps'][0]['banner'] = upload.url template_json["steps"][0]["banner"] = upload.url
template_json['steps'][0]['banner_upload_id'] = upload.id template_json["steps"][0]["banner_upload_id"] = upload.id
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
wizard_record = CustomWizard::Template.find_record(template_json["id"]) wizard_record = CustomWizard::Template.find_record(template_json["id"])
expect( expect(
UploadReference.exists?( UploadReference.exists?(
upload_id: upload.id, upload_id: upload.id,
target_type: "PluginStoreRow", target_type: "PluginStoreRow",
target_id: wizard_record.id target_id: wizard_record.id,
) ),
).to eq(true) ).to eq(true)
end end
it "are added if a wizard has a field image" do it "are added if a wizard has a field image" do
template_json['steps'][0]["fields"][0]['image'] = upload.url template_json["steps"][0]["fields"][0]["image"] = upload.url
template_json['steps'][0]["fields"][0]['image_upload_id'] = upload.id template_json["steps"][0]["fields"][0]["image_upload_id"] = upload.id
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
wizard_record = CustomWizard::Template.find_record(template_json["id"]) wizard_record = CustomWizard::Template.find_record(template_json["id"])
expect( expect(
UploadReference.exists?( UploadReference.exists?(
upload_id: upload.id, upload_id: upload.id,
target_type: "PluginStoreRow", target_type: "PluginStoreRow",
target_id: wizard_record.id target_id: wizard_record.id,
) ),
).to eq(true) ).to eq(true)
end end
it "are removed if a wizard step banner is removed" do it "are removed if a wizard step banner is removed" do
template_json['steps'][0]['banner'] = upload.url template_json["steps"][0]["banner"] = upload.url
template_json['steps'][0]['banner_upload_id'] = upload.id template_json["steps"][0]["banner_upload_id"] = upload.id
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
template_json['steps'][0]['banner'] = nil template_json["steps"][0]["banner"] = nil
template_json['steps'][0]['banner_upload_id'] = nil template_json["steps"][0]["banner_upload_id"] = nil
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
wizard_record = CustomWizard::Template.find_record(template_json["id"]) wizard_record = CustomWizard::Template.find_record(template_json["id"])
expect( expect(UploadReference.exists?(target_type: "PluginStoreRow")).to eq(false)
UploadReference.exists?(target_type: "PluginStoreRow")
).to eq(false)
end end
it "are removed if a wizard field image is removed" do it "are removed if a wizard field image is removed" do
template_json['steps'][0]["fields"][0]['image'] = upload.url template_json["steps"][0]["fields"][0]["image"] = upload.url
template_json['steps'][0]["fields"][0]['image_upload_id'] = upload.id template_json["steps"][0]["fields"][0]["image_upload_id"] = upload.id
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
template_json['steps'][0]["fields"][0]['image'] = nil template_json["steps"][0]["fields"][0]["image"] = nil
template_json['steps'][0]["fields"][0]['image_upload_id'] = nil template_json["steps"][0]["fields"][0]["image_upload_id"] = nil
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
wizard_record = CustomWizard::Template.find_record(template_json["id"]) wizard_record = CustomWizard::Template.find_record(template_json["id"])
expect( expect(UploadReference.exists?(target_type: "PluginStoreRow")).to eq(false)
UploadReference.exists?(target_type: "PluginStoreRow")
).to eq(false)
end end
it "are removed if a wizard is removed" do it "are removed if a wizard is removed" do
template_json['steps'][0]["fields"][0]['image'] = upload.url template_json["steps"][0]["fields"][0]["image"] = upload.url
template_json['steps'][0]["fields"][0]['image_upload_id'] = upload.id template_json["steps"][0]["fields"][0]["image_upload_id"] = upload.id
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
CustomWizard::Template.remove(template_json["id"]) CustomWizard::Template.remove(template_json["id"])
expect( expect(UploadReference.exists?(target_type: "PluginStoreRow")).to eq(false)
UploadReference.exists?(target_type: "PluginStoreRow")
).to eq(false)
end end
end end
context "wizard template list" do context "wizard template list" do
before do before do
enable_subscription('standard') enable_subscription("standard")
template_json_2 = template_json.dup template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2' template_json_2["id"] = "super_mega_fun_wizard_2"
template_json_2["permitted"] = permitted_json['permitted'] template_json_2["permitted"] = permitted_json["permitted"]
CustomWizard::Template.save(template_json_2, skip_jobs: true) CustomWizard::Template.save(template_json_2, skip_jobs: true)
template_json_3 = template_json.dup template_json_3 = template_json.dup
template_json_3["id"] = 'super_mega_fun_wizard_3' template_json_3["id"] = "super_mega_fun_wizard_3"
template_json_3["after_signup"] = true template_json_3["after_signup"] = true
CustomWizard::Template.save(template_json_3, skip_jobs: true) CustomWizard::Template.save(template_json_3, skip_jobs: true)
end end
it "works" do it "works" do
expect( expect(CustomWizard::Template.list.length).to eq(3)
CustomWizard::Template.list.length
).to eq(3)
end end
it "can be filtered by wizard settings" do it "can be filtered by wizard settings" do
expect( expect(CustomWizard::Template.list(setting: "after_signup").length).to eq(1)
CustomWizard::Template.list(setting: "after_signup").length
).to eq(1)
end end
it "can be ordered" do it "can be ordered" do
expect( expect(
CustomWizard::Template.list( CustomWizard::Template.list(order: "(value::json ->> 'permitted') IS NOT NULL DESC").first[
order: "(value::json ->> 'permitted') IS NOT NULL DESC" "id"
).first['id'] ],
).to eq('super_mega_fun_wizard_2') ).to eq("super_mega_fun_wizard_2")
end end
end end
@ -160,15 +141,15 @@ describe CustomWizard::Template do
@after_time_template["after_time_scheduled"] = @scheduled_time @after_time_template["after_time_scheduled"] = @scheduled_time
end end
it 'if enabled queues jobs after wizard is saved' do it "if enabled queues jobs after wizard is saved" do
expect_enqueued_with(job: :set_after_time_wizard, at: Time.parse(@scheduled_time).utc) do expect_enqueued_with(job: :set_after_time_wizard, at: Time.parse(@scheduled_time).utc) do
CustomWizard::Template.save(@after_time_template) CustomWizard::Template.save(@after_time_template)
end end
end end
it 'if disabled clears jobs after wizard is saved' do it "if disabled clears jobs after wizard is saved" do
CustomWizard::Template.save(@after_time_template) CustomWizard::Template.save(@after_time_template)
@after_time_template['after_time'] = false @after_time_template["after_time"] = false
expect_not_enqueued_with(job: :set_after_time_wizard) do expect_not_enqueued_with(job: :set_after_time_wizard) do
CustomWizard::Template.save(@after_time_template) CustomWizard::Template.save(@after_time_template)

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::TemplateValidator do describe CustomWizard::TemplateValidator do
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
let(:create_category) { get_wizard_fixture("actions/create_category") } let(:create_category) { get_wizard_fixture("actions/create_category") }
let(:user_condition) { get_wizard_fixture("condition/user_condition") } let(:user_condition) { get_wizard_fixture("condition/user_condition") }
@ -11,26 +11,20 @@ describe CustomWizard::TemplateValidator do
let(:upload_field) { get_wizard_fixture("field/upload") } let(:upload_field) { get_wizard_fixture("field/upload") }
let(:validation_condition) { get_wizard_fixture("condition/validation_condition") } let(:validation_condition) { get_wizard_fixture("condition/validation_condition") }
let(:valid_liquid_template) { let(:valid_liquid_template) { <<-LIQUID.strip }
<<-LIQUID.strip
{%- assign hello = "Topic Form 1" %} {%- assign hello = "Topic Form 1" %}
LIQUID LIQUID
}
let(:invalid_liquid_template) { let(:invalid_liquid_template) { <<-LIQUID.strip }
<<-LIQUID.strip
{%- assign hello = "Topic Form 1" % {%- assign hello = "Topic Form 1" %
LIQUID LIQUID
}
let(:liquid_syntax_error) { let(:liquid_syntax_error) do
"Liquid syntax error: Tag '{%' was not properly terminated with regexp: /\\%\\}/" "Liquid syntax error: Tag '{%' was not properly terminated with regexp: /\\%\\}/"
} end
def expect_validation_success def expect_validation_success
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
def expect_validation_failure(object_id, message) def expect_validation_failure(object_id, message)
@ -40,23 +34,17 @@ describe CustomWizard::TemplateValidator do
end end
it "validates valid templates" do it "validates valid templates" do
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
it "invalidates templates without required attributes" do it "invalidates templates without required attributes" do
template.delete(:id) template.delete(:id)
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
it "invalidates templates with duplicate ids if creating a new template" do it "invalidates templates with duplicate ids if creating a new template" do
CustomWizard::Template.save(template) CustomWizard::Template.save(template)
expect( expect(CustomWizard::TemplateValidator.new(template, create: true).perform).to eq(false)
CustomWizard::TemplateValidator.new(template, create: true).perform
).to eq(false)
end end
it "only allows one after signup wizard at a time" do it "only allows one after signup wizard at a time" do
@ -70,7 +58,7 @@ describe CustomWizard::TemplateValidator do
validator = CustomWizard::TemplateValidator.new(template) validator = CustomWizard::TemplateValidator.new(template)
expect(validator.perform).to eq(false) expect(validator.perform).to eq(false)
expect(validator.errors.first.type).to eq( expect(validator.errors.first.type).to eq(
I18n.t("wizard.validation.after_signup", wizard_id: wizard_id) I18n.t("wizard.validation.after_signup", wizard_id: wizard_id),
) )
end end
@ -86,138 +74,106 @@ describe CustomWizard::TemplateValidator do
validator = CustomWizard::TemplateValidator.new(template) validator = CustomWizard::TemplateValidator.new(template)
expect(validator.perform).to eq(false) expect(validator.perform).to eq(false)
expect(validator.errors.first.type).to eq( expect(validator.errors.first.type).to eq(I18n.t("wizard.validation.after_signup_after_time"))
I18n.t("wizard.validation.after_signup_after_time")
)
end end
it "validates after time settings" do it "validates after time settings" do
template[:after_time] = true template[:after_time] = true
template[:after_time_scheduled] = (Time.now + 3.hours).iso8601 template[:after_time_scheduled] = (Time.now + 3.hours).iso8601
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
it "invalidates invalid after time settings" do it "invalidates invalid after time settings" do
template[:after_time] = true template[:after_time] = true
template[:after_time_scheduled] = "not a time" template[:after_time_scheduled] = "not a time"
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
context "without subscription" do context "without subscription" do
it "invalidates subscription wizard attributes" do it "invalidates subscription wizard attributes" do
template[:permitted] = permitted_json['permitted'] template[:permitted] = permitted_json["permitted"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
it "invalidates subscription step attributes" do it "invalidates subscription step attributes" do
template[:steps][0][:condition] = user_condition['condition'] template[:steps][0][:condition] = user_condition["condition"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
it "invalidates subscription field attributes" do it "invalidates subscription field attributes" do
template[:steps][0][:fields][0][:condition] = user_condition['condition'] template[:steps][0][:fields][0][:condition] = user_condition["condition"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
it "invalidates subscription actions" do it "invalidates subscription actions" do
template[:actions] << create_category template[:actions] << create_category
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
end end
context "with subscription" do context "with subscription" do
before do before { enable_subscription("business") }
enable_subscription("business")
end
it "validates wizard attributes" do it "validates wizard attributes" do
template[:permitted] = permitted_json['permitted'] template[:permitted] = permitted_json["permitted"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
it "validates user-only features" do it "validates user-only features" do
template[:permitted] = guests_permitted['permitted'] template[:permitted] = guests_permitted["permitted"]
template[:steps][0][:fields] << upload_field template[:steps][0][:fields] << upload_field
validator = CustomWizard::TemplateValidator.new(template) validator = CustomWizard::TemplateValidator.new(template)
expect(validator.perform).to eq(false) expect(validator.perform).to eq(false)
errors = validator.errors.to_a errors = validator.errors.to_a
expect(errors).to include( expect(errors).to include(
I18n.t("wizard.validation.not_permitted_for_guests", object_id: "step_2_field_7") I18n.t("wizard.validation.not_permitted_for_guests", object_id: "step_2_field_7"),
) )
end end
it "validates step attributes" do it "validates step attributes" do
template[:steps][0][:condition] = user_condition['condition'] template[:steps][0][:condition] = user_condition["condition"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
it "validates field attributes" do it "validates field attributes" do
template[:steps][0][:fields][0][:condition] = user_condition['condition'] template[:steps][0][:fields][0][:condition] = user_condition["condition"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
it "validates actions" do it "validates actions" do
template[:actions] << create_category template[:actions] << create_category
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
it "validates settings with validation conditions" do it "validates settings with validation conditions" do
template[:permitted] = validation_condition["condition"] template[:permitted] = validation_condition["condition"]
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end end
end end
context "steps" do context "steps" do
CustomWizard::TemplateValidator.required[:step].each do |attribute| CustomWizard::TemplateValidator.required[:step].each do |attribute|
it "invalidates if \"#{attribute.to_s}\" is not present" do it "invalidates if \"#{attribute}\" is not present" do
template[:steps][0][attribute] = nil template[:steps][0][attribute] = nil
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
end end
end end
context "fields" do context "fields" do
CustomWizard::TemplateValidator.required[:field].each do |attribute| CustomWizard::TemplateValidator.required[:field].each do |attribute|
it "invalidates if \"#{attribute.to_s}\" is not present" do it "invalidates if \"#{attribute}\" is not present" do
template[:steps][0][:fields][0][attribute] = nil template[:steps][0][:fields][0][attribute] = nil
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
end end
end end
context "actions" do context "actions" do
CustomWizard::TemplateValidator.required[:action].each do |attribute| CustomWizard::TemplateValidator.required[:action].each do |attribute|
it "invalidates if \"#{attribute.to_s}\" is not present" do it "invalidates if \"#{attribute}\" is not present" do
template[:actions][0][attribute] = nil template[:actions][0][attribute] = nil
expect( expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end end
end end
end end

Datei anzeigen

@ -1,13 +1,13 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::UpdateValidator do describe CustomWizard::UpdateValidator do
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
let(:url_field) { get_wizard_fixture("field/url") } let(:url_field) { get_wizard_fixture("field/url") }
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find("super_mega_fun_wizard")
end end
def perform_validation(step_id, submission) def perform_validation(step_id, submission)
@ -17,7 +17,7 @@ describe CustomWizard::UpdateValidator do
updater updater
end end
it 'applies min length to text type fields' do it "applies min length to text type fields" do
min_length = 3 min_length = 3
@template[:steps][0][:fields][0][:min_length] = min_length @template[:steps][0][:fields][0][:min_length] = min_length
@ -25,34 +25,35 @@ describe CustomWizard::UpdateValidator do
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_1', step_1_field_1: 'Te') updater = perform_validation("step_1", step_1_field_1: "Te")
expect( expect(updater.errors.messages[:step_1_field_1].first).to eq(
updater.errors.messages[:step_1_field_1].first I18n.t("wizard.field.too_short", label: "Text", min: min_length),
).to eq(I18n.t('wizard.field.too_short', label: 'Text', min: min_length)) )
updater = perform_validation('step_1', step_1_field_2: 'Te') updater = perform_validation("step_1", step_1_field_2: "Te")
expect( expect(updater.errors.messages[:step_1_field_2].first).to eq(
updater.errors.messages[:step_1_field_2].first I18n.t("wizard.field.too_short", label: "Textarea", min: min_length),
).to eq(I18n.t('wizard.field.too_short', label: 'Textarea', min: min_length)) )
end end
it 'prevents submission if the length is over the max length' do it "prevents submission if the length is over the max length" do
max_length = 100 max_length = 100
@template[:steps][0][:fields][0][:max_length] = max_length @template[:steps][0][:fields][0][:max_length] = max_length
@template[:steps][0][:fields][1][:max_length] = max_length @template[:steps][0][:fields][1][:max_length] = max_length
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
long_string = "Our Competitive Capability solution offers platforms a suite of wholesale offerings. In the future, will you be able to effectively revolutionize synergies in your business? In the emerging market space, industry is ethically investing its mission critical executive searches. Key players will take ownership of their capabilities by iteratively right-sizing world-class visibilities. " long_string =
updater = perform_validation('step_1', step_1_field_1: long_string) "Our Competitive Capability solution offers platforms a suite of wholesale offerings. In the future, will you be able to effectively revolutionize synergies in your business? In the emerging market space, industry is ethically investing its mission critical executive searches. Key players will take ownership of their capabilities by iteratively right-sizing world-class visibilities. "
expect( updater = perform_validation("step_1", step_1_field_1: long_string)
updater.errors.messages[:step_1_field_1].first expect(updater.errors.messages[:step_1_field_1].first).to eq(
).to eq(I18n.t('wizard.field.too_long', label: 'Text', max: max_length)) I18n.t("wizard.field.too_long", label: "Text", max: max_length),
)
updater = perform_validation('step_1', step_1_field_2: long_string) updater = perform_validation("step_1", step_1_field_2: long_string)
expect( expect(updater.errors.messages[:step_1_field_2].first).to eq(
updater.errors.messages[:step_1_field_2].first I18n.t("wizard.field.too_long", label: "Textarea", max: max_length),
).to eq(I18n.t('wizard.field.too_long', label: 'Textarea', max: max_length)) )
end end
it "allows submission if the length is under or equal to the max length" do it "allows submission if the length is under or equal to the max length" do
@ -62,16 +63,13 @@ describe CustomWizard::UpdateValidator do
@template[:steps][0][:fields][1][:max_length] = max_length @template[:steps][0][:fields][1][:max_length] = max_length
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
hundred_chars_string = "This is a line, exactly hundred characters long and not more even a single character more than that." hundred_chars_string =
updater = perform_validation('step_1', step_1_field_1: hundred_chars_string) "This is a line, exactly hundred characters long and not more even a single character more than that."
expect( updater = perform_validation("step_1", step_1_field_1: hundred_chars_string)
updater.errors.messages[:step_1_field_1].first expect(updater.errors.messages[:step_1_field_1].first).to eq(nil)
).to eq(nil)
updater = perform_validation('step_1', step_1_field_2: hundred_chars_string) updater = perform_validation("step_1", step_1_field_2: hundred_chars_string)
expect( expect(updater.errors.messages[:step_1_field_2].first).to eq(nil)
updater.errors.messages[:step_1_field_2].first
).to eq(nil)
end end
it "applies min length only if the input is non-empty" do it "applies min length only if the input is non-empty" do
@ -81,10 +79,8 @@ describe CustomWizard::UpdateValidator do
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_1', step_1_field_1: '') updater = perform_validation("step_1", step_1_field_1: "")
expect( expect(updater.errors.messages[:step_1_field_1].first).to eq(nil)
updater.errors.messages[:step_1_field_1].first
).to eq(nil)
end end
it "applies max length only if the input is non-empty" do it "applies max length only if the input is non-empty" do
@ -93,93 +89,81 @@ describe CustomWizard::UpdateValidator do
@template[:steps][0][:fields][0][:max_length] = max_length @template[:steps][0][:fields][0][:max_length] = max_length
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_1', step_1_field_1: "") updater = perform_validation("step_1", step_1_field_1: "")
expect( expect(updater.errors.messages[:step_1_field_1].first).to eq(nil)
updater.errors.messages[:step_1_field_1].first
).to eq(nil)
end end
it 'standardises boolean entries' do it "standardises boolean entries" do
updater = perform_validation('step_2', step_2_field_5: 'false') updater = perform_validation("step_2", step_2_field_5: "false")
expect(updater.submission['step_2_field_5']).to eq(false) expect(updater.submission["step_2_field_5"]).to eq(false)
end end
it 'requires required fields' do it "requires required fields" do
@template[:steps][0][:fields][1][:required] = true @template[:steps][0][:fields][1][:required] = true
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_1', step_1_field_2: nil) updater = perform_validation("step_1", step_1_field_2: nil)
expect( expect(updater.errors.messages[:step_1_field_2].first).to eq(
updater.errors.messages[:step_1_field_2].first I18n.t("wizard.field.required", label: "Textarea"),
).to eq(I18n.t('wizard.field.required', label: 'Textarea')) )
end end
context "subscription fields" do context "subscription fields" do
before do before { enable_subscription("standard") }
enable_subscription("standard")
it "validates url fields" do
updater = perform_validation("step_2", step_2_field_6: "https://discourse.com")
expect(updater.errors.messages[:step_2_field_6].first).to eq(nil)
end end
it 'validates url fields' do it "does not validate url fields with non-url inputs" do
updater = perform_validation('step_2', step_2_field_6: 'https://discourse.com')
expect(
updater.errors.messages[:step_2_field_6].first
).to eq(nil)
end
it 'does not validate url fields with non-url inputs' do
template[:steps][0][:fields] << url_field template[:steps][0][:fields] << url_field
CustomWizard::Template.save(template) CustomWizard::Template.save(template)
updater = perform_validation('step_1', step_2_field_6: 'discourse') updater = perform_validation("step_1", step_2_field_6: "discourse")
expect( expect(updater.errors.messages[:step_2_field_6].first).to eq(
updater.errors.messages[:step_2_field_6].first I18n.t("wizard.field.not_url", label: "Url"),
).to eq(I18n.t('wizard.field.not_url', label: 'Url')) )
end end
it 'validates empty url fields' do it "validates empty url fields" do
updater = perform_validation('step_2', step_2_field_6: '') updater = perform_validation("step_2", step_2_field_6: "")
expect( expect(updater.errors.messages[:step_2_field_6].first).to eq(nil)
updater.errors.messages[:step_2_field_6].first
).to eq(nil)
end end
end end
it 'validates date fields' do it "validates date fields" do
@template[:steps][1][:fields][0][:format] = "DD-MM-YYYY" @template[:steps][1][:fields][0][:format] = "DD-MM-YYYY"
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_2', step_2_field_1: '13-11-2021') updater = perform_validation("step_2", step_2_field_1: "13-11-2021")
expect( expect(updater.errors.messages[:step_2_field_1].first).to eq(nil)
updater.errors.messages[:step_2_field_1].first
).to eq(nil)
end end
it 'doesn\'t validate date field if the format is not respected' do it 'doesn\'t validate date field if the format is not respected' do
@template[:steps][1][:fields][0][:format] = "MM-DD-YYYY" @template[:steps][1][:fields][0][:format] = "MM-DD-YYYY"
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_2', step_2_field_1: '13-11-2021') updater = perform_validation("step_2", step_2_field_1: "13-11-2021")
expect( expect(updater.errors.messages[:step_2_field_1].first).to eq(
updater.errors.messages[:step_2_field_1].first I18n.t("wizard.field.invalid_date"),
).to eq(I18n.t('wizard.field.invalid_date')) )
end end
it 'validates date time fields' do it "validates date time fields" do
@template[:steps][1][:fields][2][:format] = "DD-MM-YYYY HH:mm:ss" @template[:steps][1][:fields][2][:format] = "DD-MM-YYYY HH:mm:ss"
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_2', step_2_field_3: '13-11-2021 09:15:00') updater = perform_validation("step_2", step_2_field_3: "13-11-2021 09:15:00")
expect( expect(updater.errors.messages[:step_2_field_3].first).to eq(nil)
updater.errors.messages[:step_2_field_3].first
).to eq(nil)
end end
it 'doesn\'t validate date time field if the format is not respected' do it 'doesn\'t validate date time field if the format is not respected' do
@template[:steps][1][:fields][2][:format] = "MM-DD-YYYY HH:mm:ss" @template[:steps][1][:fields][2][:format] = "MM-DD-YYYY HH:mm:ss"
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_2', step_2_field_3: '13-11-2021 09:15') updater = perform_validation("step_2", step_2_field_3: "13-11-2021 09:15")
expect( expect(updater.errors.messages[:step_2_field_3].first).to eq(
updater.errors.messages[:step_2_field_3].first I18n.t("wizard.field.invalid_date"),
).to eq(I18n.t('wizard.field.invalid_date')) )
end end
end end

Datei anzeigen

@ -19,9 +19,7 @@ describe CustomWizard::Wizard do
end end
def append_steps def append_steps
template_json['steps'].each do |step_template| template_json["steps"].each { |step_template| @wizard.append_step(step_template["id"]) }
@wizard.append_step(step_template['id'])
end
@wizard.update! @wizard.update!
end end
@ -30,7 +28,7 @@ describe CustomWizard::Wizard do
action: CustomWizard::UserHistory.actions[:step], action: CustomWizard::UserHistory.actions[:step],
actor_id: actor_id, actor_id: actor_id,
context: wizard.id, context: wizard.id,
subject: step_id subject: step_id,
) )
@wizard.update! @wizard.update!
end end
@ -47,13 +45,13 @@ describe CustomWizard::Wizard do
end end
it "appends steps with custom indexes" do it "appends steps with custom indexes" do
template_json['steps'][0]['index'] = 2 template_json["steps"][0]["index"] = 2
template_json['steps'][1]['index'] = 1 template_json["steps"][1]["index"] = 1
template_json['steps'][2]['index'] = 0 template_json["steps"][2]["index"] = 0
template_json['steps'].each do |step_template| template_json["steps"].each do |step_template|
@wizard.append_step(step_template['id']) do |step| @wizard.append_step(step_template["id"]) do |step|
step.index = step_template['index'] if step_template['index'] step.index = step_template["index"] if step_template["index"]
end end
end end
@ -71,38 +69,35 @@ describe CustomWizard::Wizard do
it "determines the user's current step" do it "determines the user's current step" do
append_steps append_steps
expect(@wizard.start).to eq('step_1') expect(@wizard.start).to eq("step_1")
progress_step('step_1') progress_step("step_1")
expect(@wizard.start).to eq('step_2') expect(@wizard.start).to eq("step_2")
end end
it "determines the user's current step if steps are added" do it "determines the user's current step if steps are added" do
append_steps append_steps
progress_step('step_1') progress_step("step_1")
progress_step('step_2') progress_step("step_2")
progress_step("step_3") progress_step("step_3")
fourth_step = step_json.dup fourth_step = step_json.dup
fourth_step['id'] = "step_4" fourth_step["id"] = "step_4"
template = template_json.dup template = template_json.dup
template['steps'] << fourth_step template["steps"] << fourth_step
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
wizard = CustomWizard::Wizard.new(template, user) wizard = CustomWizard::Wizard.new(template, user)
template['steps'].each do |step_template| template["steps"].each { |step_template| wizard.append_step(step_template["id"]) }
wizard.append_step(step_template['id'])
end
expect(wizard.steps.size).to eq(4) expect(wizard.steps.size).to eq(4)
expect(wizard.start).to eq(nil) expect(wizard.start).to eq(nil)
end end
it "creates a step updater" do it "creates a step updater" do
expect( expect(@wizard.create_updater("step_1", step_1_field_1: "Text input").class).to eq(
@wizard.create_updater('step_1', step_1_field_1: "Text input") CustomWizard::StepUpdater,
.class )
).to eq(CustomWizard::StepUpdater)
end end
it "determines whether a wizard is unfinished" do it "determines whether a wizard is unfinished" do
@ -133,8 +128,8 @@ describe CustomWizard::Wizard do
progress_step("step_2") progress_step("step_2")
progress_step("step_3") progress_step("step_3")
template_json['after_time'] = true template_json["after_time"] = true
template_json['after_time_scheduled'] = Time.now + 3.hours template_json["after_time_scheduled"] = Time.now + 3.hours
wizard = CustomWizard::Wizard.new(template_json, user) wizard = CustomWizard::Wizard.new(template_json, user)
expect(wizard.completed?).to eq(true) expect(wizard.completed?).to eq(true)
@ -149,9 +144,9 @@ describe CustomWizard::Wizard do
progress_step("step_2") progress_step("step_2")
progress_step("step_3") progress_step("step_3")
template_json['after_time'] = true template_json["after_time"] = true
template_json['multiple_submissions'] = true template_json["multiple_submissions"] = true
template_json['after_time_scheduled'] = Time.now + 3.hours template_json["after_time_scheduled"] = Time.now + 3.hours
wizard = CustomWizard::Wizard.new(template_json, user) wizard = CustomWizard::Wizard.new(template_json, user)
expect(wizard.completed?).to eq(false) expect(wizard.completed?).to eq(false)
@ -159,45 +154,31 @@ describe CustomWizard::Wizard do
end end
context "with subscription" do context "with subscription" do
before do before { enable_subscription("standard") }
enable_subscription("standard")
end
it "permits admins" do it "permits admins" do
expect( expect(CustomWizard::Wizard.new(@permitted_template, admin_user).permitted?).to eq(true)
CustomWizard::Wizard.new(@permitted_template, admin_user).permitted?
).to eq(true)
end end
it "permits permitted users" do it "permits permitted users" do
expect( expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted?).to eq(true)
CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted?
).to eq(true)
end end
it "permits everyone if everyone is permitted" do it "permits everyone if everyone is permitted" do
@permitted_template['permitted'][0]['output'] = Group::AUTO_GROUPS[:everyone] @permitted_template["permitted"][0]["output"] = Group::AUTO_GROUPS[:everyone]
expect( expect(CustomWizard::Wizard.new(@permitted_template, user).permitted?).to eq(true)
CustomWizard::Wizard.new(@permitted_template, user).permitted?
).to eq(true)
end end
it "does not permit unpermitted users" do it "does not permit unpermitted users" do
expect( expect(CustomWizard::Wizard.new(@permitted_template, user).permitted?).to eq(false)
CustomWizard::Wizard.new(@permitted_template, user).permitted?
).to eq(false)
end end
it "does not let an unpermitted user access a wizard" do it "does not let an unpermitted user access a wizard" do
expect( expect(CustomWizard::Wizard.new(@permitted_template, user).can_access?).to eq(false)
CustomWizard::Wizard.new(@permitted_template, user).can_access?
).to eq(false)
end end
it "lets a permitted user access an incomplete wizard" do it "lets a permitted user access an incomplete wizard" do
expect( expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?).to eq(true)
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
).to eq(true)
end end
it "lets a permitted user access a complete wizard with multiple submissions" do it "lets a permitted user access a complete wizard with multiple submissions" do
@ -209,9 +190,7 @@ describe CustomWizard::Wizard do
@permitted_template["multiple_submissions"] = true @permitted_template["multiple_submissions"] = true
expect( expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?).to eq(true)
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
).to eq(true)
end end
it "does not let an unpermitted user access a complete wizard without multiple submissions" do it "does not let an unpermitted user access a complete wizard without multiple submissions" do
@ -221,27 +200,21 @@ describe CustomWizard::Wizard do
progress_step("step_2", actor_id: trusted_user.id) progress_step("step_2", actor_id: trusted_user.id)
progress_step("step_3", actor_id: trusted_user.id) progress_step("step_3", actor_id: trusted_user.id)
@permitted_template['multiple_submissions'] = false @permitted_template["multiple_submissions"] = false
expect( expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?).to eq(false)
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
).to eq(false)
end end
it "sets wizard redirects if user is permitted" do it "sets wizard redirects if user is permitted" do
CustomWizard::Template.save(@permitted_template, skip_jobs: true) CustomWizard::Template.save(@permitted_template, skip_jobs: true)
CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', trusted_user) CustomWizard::Wizard.set_user_redirect("super_mega_fun_wizard", trusted_user)
expect( expect(trusted_user.custom_fields["redirect_to_wizard"]).to eq("super_mega_fun_wizard")
trusted_user.custom_fields['redirect_to_wizard']
).to eq("super_mega_fun_wizard")
end end
it "does not set a wizard redirect if user is not permitted" do it "does not set a wizard redirect if user is not permitted" do
CustomWizard::Template.save(@permitted_template, skip_jobs: true) CustomWizard::Template.save(@permitted_template, skip_jobs: true)
CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', user) CustomWizard::Wizard.set_user_redirect("super_mega_fun_wizard", user)
expect( expect(trusted_user.custom_fields["redirect_to_wizard"]).to eq(nil)
trusted_user.custom_fields['redirect_to_wizard']
).to eq(nil)
end end
end end
@ -249,47 +222,39 @@ describe CustomWizard::Wizard do
before do before do
enable_subscription("standard") enable_subscription("standard")
@wizard.restart_on_revisit = true @wizard.restart_on_revisit = true
CustomWizard::Template.save( CustomWizard::Template.save(CustomWizard::WizardSerializer.new(@wizard, root: false).as_json)
CustomWizard::WizardSerializer.new(@wizard, root: false).as_json
)
end end
it "returns to step 1 if option to clear submissions on each visit is set" do it "returns to step 1 if option to clear submissions on each visit is set" do
append_steps append_steps
expect(@wizard.unfinished?).to eq(true) expect(@wizard.unfinished?).to eq(true)
progress_step('step_1') progress_step("step_1")
expect(@wizard.start).to eq('step_1') expect(@wizard.start).to eq("step_1")
end end
end end
context "with subscription and guest wizard" do context "with subscription and guest wizard" do
before do before { enable_subscription("standard") }
enable_subscription("standard")
end
it "permits admins" do it "permits admins" do
expect( expect(CustomWizard::Wizard.new(@guests_permitted_template, admin_user).permitted?).to eq(
CustomWizard::Wizard.new(@guests_permitted_template, admin_user).permitted? true,
).to eq(true) )
end end
it "permits regular users" do it "permits regular users" do
expect( expect(CustomWizard::Wizard.new(@guests_permitted_template, user).permitted?).to eq(true)
CustomWizard::Wizard.new(@guests_permitted_template, user).permitted?
).to eq(true)
end end
it "permits guests" do it "permits guests" do
expect( expect(
CustomWizard::Wizard.new(@guests_permitted_template, nil, "guest123").permitted? CustomWizard::Wizard.new(@guests_permitted_template, nil, "guest123").permitted?,
).to eq(true) ).to eq(true)
end end
end end
context "submissions" do context "submissions" do
before do before { CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission").save }
CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission").save
end
it "lists the user's submissions" do it "lists the user's submissions" do
expect(@wizard.submissions.length).to eq(1) expect(@wizard.submissions.length).to eq(1)
@ -306,12 +271,12 @@ describe CustomWizard::Wizard do
CustomWizard::Template.save(@permitted_template, skip_jobs: true) CustomWizard::Template.save(@permitted_template, skip_jobs: true)
template_json_2 = template_json.dup template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2' template_json_2["id"] = "super_mega_fun_wizard_2"
template_json_2["prompt_completion"] = true template_json_2["prompt_completion"] = true
CustomWizard::Template.save(template_json_2, skip_jobs: true) CustomWizard::Template.save(template_json_2, skip_jobs: true)
template_json_3 = template_json.dup template_json_3 = template_json.dup
template_json_3["id"] = 'super_mega_fun_wizard_3' template_json_3["id"] = "super_mega_fun_wizard_3"
template_json_3["after_signup"] = true template_json_3["after_signup"] = true
template_json_3["prompt_completion"] = true template_json_3["prompt_completion"] = true
CustomWizard::Template.save(template_json_3, skip_jobs: true) CustomWizard::Template.save(template_json_3, skip_jobs: true)
@ -323,7 +288,7 @@ describe CustomWizard::Wizard do
end end
it "returns the first after signup wizard" do it "returns the first after signup wizard" do
expect(CustomWizard::Wizard.after_signup(user).id).to eq('super_mega_fun_wizard_3') expect(CustomWizard::Wizard.after_signup(user).id).to eq("super_mega_fun_wizard_3")
end end
it "lists prompt completion wizards" do it "lists prompt completion wizards" do
@ -331,7 +296,8 @@ describe CustomWizard::Wizard do
end end
it "prompt completion does not include wizards user has completed" do it "prompt completion does not include wizards user has completed" do
wizard_2 = CustomWizard::Wizard.new(CustomWizard::Template.find('super_mega_fun_wizard_2'), user) wizard_2 =
CustomWizard::Wizard.new(CustomWizard::Template.find("super_mega_fun_wizard_2"), user)
progress_step("step_1", wizard: wizard_2) progress_step("step_1", wizard: wizard_2)
progress_step("step_2", wizard: wizard_2) progress_step("step_2", wizard: wizard_2)
progress_step("step_3", wizard: wizard_2) progress_step("step_3", wizard: wizard_2)

Datei anzeigen

@ -5,12 +5,12 @@ describe DiscoursePluginStatistics::Plugin do
describe "#discourse_custom_wizard" do describe "#discourse_custom_wizard" do
before do before do
enable_subscription('standard') enable_subscription("standard")
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
template_json_2 = template_json.dup template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2' template_json_2["id"] = "super_mega_fun_wizard_2"
CustomWizard::Template.save(template_json_2, skip_jobs: true) CustomWizard::Template.save(template_json_2, skip_jobs: true)
@data = DiscoursePluginStatistics::Plugin.discourse_custom_wizard @data = DiscoursePluginStatistics::Plugin.discourse_custom_wizard
@ -21,7 +21,7 @@ describe DiscoursePluginStatistics::Plugin do
end end
it "includes the subscription type" do it "includes the subscription type" do
expect(@data[:subscription_type]).to eq('standard') expect(@data[:subscription_type]).to eq("standard")
end end
it "includes a count of features being used across all wizards" do it "includes a count of features being used across all wizards" do
@ -36,7 +36,7 @@ describe DiscoursePluginStatistics::Plugin do
step: { step: {
required_data: 0, required_data: 0,
permitted_params: 0, permitted_params: 0,
force_final: 0 force_final: 0,
}, },
field: { field: {
condition: 0, condition: 0,
@ -60,7 +60,7 @@ describe DiscoursePluginStatistics::Plugin do
topic: 0, topic: 0,
user_selector: 0, user_selector: 0,
}, },
realtime_validations: 0 realtime_validations: 0,
}, },
action: { action: {
type: { type: {
@ -75,8 +75,8 @@ describe DiscoursePluginStatistics::Plugin do
add_to_group: 0, add_to_group: 0,
create_group: 0, create_group: 0,
create_category: 0, create_category: 0,
} },
} },
) )
end end
end end

Datei anzeigen

@ -1,17 +1,19 @@
# frozen_string_literal: true # frozen_string_literal: true
describe "custom field extensions" do describe "custom field extensions" do
fab!(:topic) { Fabricate(:topic) } fab!(:topic)
fab!(:post) { Fabricate(:post) } fab!(:post)
fab!(:category) { Fabricate(:category) } fab!(:category)
fab!(:group) { Fabricate(:group) } fab!(:group)
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
let(:subscription_custom_field_json) { get_wizard_fixture("custom_field/subscription_custom_fields") } let(:subscription_custom_field_json) do
get_wizard_fixture("custom_field/subscription_custom_fields")
end
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save
end end
@ -27,11 +29,12 @@ describe "custom field extensions" do
topic.custom_fields["topic_field_1"] = true topic.custom_fields["topic_field_1"] = true
topic.save_custom_fields(true) topic.save_custom_fields(true)
serializer = TopicViewSerializer.new( serializer =
TopicView.new(topic.id, user), TopicViewSerializer.new(
scope: Guardian.new(user), TopicView.new(topic.id, user),
root: false scope: Guardian.new(user),
).as_json root: false,
).as_json
expect(serializer[:topic_field_1]).to eq(true) expect(serializer[:topic_field_1]).to eq(true)
end end
@ -40,11 +43,8 @@ describe "custom field extensions" do
topic.custom_fields["topic_field_1"] = true topic.custom_fields["topic_field_1"] = true
topic.save_custom_fields(true) topic.save_custom_fields(true)
serializer = TopicListItemSerializer.new( serializer =
topic, TopicListItemSerializer.new(topic, scope: Guardian.new(user), root: false).as_json
scope: Guardian.new(user),
root: false
).as_json
expect(serializer[:topic_field_1]).to eq(true) expect(serializer[:topic_field_1]).to eq(true)
end end
@ -60,11 +60,7 @@ describe "custom field extensions" do
post.custom_fields["post_field_1"] = 7 post.custom_fields["post_field_1"] = 7
post.save_custom_fields(true) post.save_custom_fields(true)
serializer = PostSerializer.new( serializer = PostSerializer.new(post, scope: Guardian.new(user), root: false).as_json
post,
scope: Guardian.new(user),
root: false
).as_json
expect(serializer[:post_field_1]).to eq(7) expect(serializer[:post_field_1]).to eq(7)
end end
@ -74,7 +70,7 @@ describe "custom field extensions" do
before do before do
enable_subscription("business") enable_subscription("business")
subscription_custom_field_json['custom_fields'].each do |field_json| subscription_custom_field_json["custom_fields"].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save
end end
@ -90,11 +86,8 @@ describe "custom field extensions" do
category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json
category.save_custom_fields(true) category.save_custom_fields(true)
serializer = BasicCategorySerializer.new( serializer =
category, BasicCategorySerializer.new(category, scope: Guardian.new(user), root: false).as_json
scope: Guardian.new(user),
root: false
).as_json
expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json) expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json)
end end
@ -110,11 +103,7 @@ describe "custom field extensions" do
group.custom_fields["group_field_1"] = "Hello" group.custom_fields["group_field_1"] = "Hello"
group.save_custom_fields(true) group.save_custom_fields(true)
serializer = BasicGroupSerializer.new( serializer = BasicGroupSerializer.new(group, scope: Guardian.new(user), root: false).as_json
group,
scope: Guardian.new(user),
root: false
).as_json
expect(serializer[:group_field_1]).to eq("Hello") expect(serializer[:group_field_1]).to eq("Hello")
end end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
describe ::DiscourseTagging, type: :request do describe ::DiscourseTagging, type: :request do
fab!(:user) { Fabricate(:user) } fab!(:user)
fab!(:tag_1) { Fabricate(:tag, name: "Angus") } fab!(:tag_1) { Fabricate(:tag, name: "Angus") }
fab!(:tag_2) { Fabricate(:tag, name: "Faizaan") } fab!(:tag_2) { Fabricate(:tag, name: "Faizaan") }
fab!(:tag_3) { Fabricate(:tag, name: "Robert") } fab!(:tag_3) { Fabricate(:tag, name: "Robert") }
@ -16,10 +16,7 @@ describe ::DiscourseTagging, type: :request do
context "for_input is a boolean" do context "for_input is a boolean" do
it "works normally" do it "works normally" do
filter_params = { filter_params = { q: "", for_input: true }
q: '',
for_input: true
}
tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params) tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params)
names = tags.map(&:name) names = tags.map(&:name)
all_tag_names = Tag.all.pluck(:name) all_tag_names = Tag.all.pluck(:name)
@ -33,15 +30,17 @@ describe ::DiscourseTagging, type: :request do
q: "", q: "",
for_input: { for_input: {
name: "custom-wizard-tag-chooser", name: "custom-wizard-tag-chooser",
groups: tag_group_1.name groups: tag_group_1.name,
} },
} }
tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params) tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params)
names = tags.map(&:name) names = tags.map(&:name)
expected_tag_names = TagGroup expected_tag_names =
.includes(:tags) TagGroup
.where(id: tag_group_1.id) .includes(:tags)
.map { |tag_group| tag_group.tags.pluck(:name) }.flatten .where(id: tag_group_1.id)
.map { |tag_group| tag_group.tags.pluck(:name) }
.flatten
expect(names).to contain_exactly(*expected_tag_names) expect(names).to contain_exactly(*expected_tag_names)
end end
@ -49,13 +48,7 @@ describe ::DiscourseTagging, type: :request do
context "for_input is an object including an empty tag group string" do context "for_input is an object including an empty tag group string" do
it "returns all tags" do it "returns all tags" do
filter_params = { filter_params = { q: "", for_input: { name: "custom-wizard-tag-chooser", groups: "" } }
q: "",
for_input: {
name: "custom-wizard-tag-chooser",
groups: ""
}
}
tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params) tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params)
names = tags.map(&:name) names = tags.map(&:name)

Datei anzeigen

@ -6,9 +6,7 @@ describe ExtraLocalesControllerCustomWizard, type: :request do
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
let(:permitted) { get_wizard_fixture("wizard/permitted") } let(:permitted) { get_wizard_fixture("wizard/permitted") }
before do before { CustomWizard::Template.save(template, skip_jobs: true) }
CustomWizard::Template.save(template, skip_jobs: true)
end
before do before do
js_hash = ExtraLocalesController.bundle_js_hash("wizard") js_hash = ExtraLocalesController.bundle_js_hash("wizard")
@ -22,14 +20,14 @@ describe ExtraLocalesControllerCustomWizard, type: :request do
it "returns wizard locales when requested by user in wizard" do it "returns wizard locales when requested by user in wizard" do
sign_in(new_user) sign_in(new_user)
get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard" } get @locale_url, headers: { "REFERER" => "/w/super-mega-fun-wizard" }
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
it "returns wizard locales when requested by user in a wizard step" do it "returns wizard locales when requested by user in a wizard step" do
sign_in(new_user) sign_in(new_user)
get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard/steps/step_1" } get @locale_url, headers: { "REFERER" => "/w/super-mega-fun-wizard/steps/step_1" }
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
@ -38,7 +36,7 @@ describe ExtraLocalesControllerCustomWizard, type: :request do
CustomWizard::Template.save(template.as_json) CustomWizard::Template.save(template.as_json)
sign_in(new_user) sign_in(new_user)
get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard" } get @locale_url, headers: { "REFERER" => "/w/super-mega-fun-wizard" }
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end

Datei anzeigen

@ -1,40 +1,31 @@
# frozen_string_literal: true # frozen_string_literal: true
describe ::Guardian do describe ::Guardian do
fab!(:user) { fab!(:user) { Fabricate(:user, name: "Angus", username: "angus", email: "angus@email.com") }
Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com") fab!(:category) { Fabricate(:category, name: "cat1", slug: "cat-slug") }
} let(:wizard_template) do
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') }
let(:wizard_template) {
JSON.parse( JSON.parse(
File.open( File.open("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json").read,
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read
) )
} end
def create_topic_by_wizard(wizard) def create_topic_by_wizard(wizard)
wizard.create_updater( wizard.create_updater(
wizard.steps.first.id, wizard.steps.first.id,
step_1_field_1: "Topic Title", step_1_field_1: "Topic Title",
step_1_field_2: "topic body" step_1_field_2: "topic body",
).update ).update
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
step_3_field_3: category.id
).update
topic = Topic.where( topic = Topic.where(title: "Topic Title", category_id: category.id).first
title: "Topic Title",
category_id: category.id
).first
topic topic
end end
before do before do
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find("super_mega_fun_wizard")
end end
context "topic created by user using wizard" do context "topic created by user using wizard" do
@ -47,11 +38,7 @@ describe ::Guardian do
context "topic created by user without wizard" do context "topic created by user without wizard" do
it "restricts editing the topic first post" do it "restricts editing the topic first post" do
topic_params = { topic_params = { title: "Topic Title", raw: "Topic body", skip_validations: true }
title: "Topic Title",
raw: "Topic body",
skip_validations: true
}
post = PostCreator.new(user, topic_params).create post = PostCreator.new(user, topic_params).create
expect(user.guardian.wizard_can_edit_topic?(post.topic)).to be_falsey expect(user.guardian.wizard_can_edit_topic?(post.topic)).to be_falsey
end end

Datei anzeigen

@ -1,16 +1,14 @@
# frozen_string_literal: true # frozen_string_literal: true
describe InvitesControllerCustomWizard, type: :request do describe InvitesControllerCustomWizard, type: :request do
fab!(:topic) { Fabricate(:topic) } fab!(:topic)
let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) } let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) }
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
before do before { @controller = InvitesController.new }
@controller = InvitesController.new
end
it "redirects a user to wizard after invite if after signup is enabled" do it "redirects a user to wizard after invite if after signup is enabled" do
template['after_signup'] = true template["after_signup"] = true
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
put "/invites/show/#{invite.invite_key}.json" put "/invites/show/#{invite.invite_key}.json"
expect(cookies[:destination_url]).to eq("/w/super-mega-fun-wizard") expect(cookies[:destination_url]).to eq("/w/super-mega-fun-wizard")

Datei anzeigen

@ -2,42 +2,39 @@
describe Topic, type: :model do describe Topic, type: :model do
fab!(:category_with_wizard) do fab!(:category_with_wizard) do
Fabricate(:category, custom_fields: { create_topic_wizard: 'true' }) Fabricate(:category, custom_fields: { create_topic_wizard: "true" })
end end
fab!(:category_without_wizard) { Fabricate(:category) } fab!(:category_without_wizard) { Fabricate(:category) }
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
let(:valid_attrs) { Fabricate.attributes_for(:topic) } let(:valid_attrs) { Fabricate.attributes_for(:topic) }
context 'with a create_topic_wizard custom field in the category' do context "with a create_topic_wizard custom field in the category" do
it 'will not allow creating a topic directly' do it "will not allow creating a topic directly" do
expect do expect do
TopicCreator.create( TopicCreator.create(
user, user,
Guardian.new(user), Guardian.new(user),
valid_attrs.merge( valid_attrs.merge(
title: 'A valid and sufficiently long title for testing', title: "A valid and sufficiently long title for testing",
category: category_with_wizard.id, category: category_with_wizard.id,
raw: 'hello this is a test topic with category with custom fields' raw: "hello this is a test topic with category with custom fields",
) ),
) )
end.to raise_error( end.to raise_error(Discourse::InvalidParameters, "Category not allowed for topic creation.")
Discourse::InvalidParameters,
'Category not allowed for topic creation.'
)
end end
end end
context 'without a create_topic_wizard custom field in the category' do context "without a create_topic_wizard custom field in the category" do
it 'will allow creating a topic directly' do it "will allow creating a topic directly" do
expect do expect do
TopicCreator.create( TopicCreator.create(
user, user,
Guardian.new(user), Guardian.new(user),
valid_attrs.merge( valid_attrs.merge(
category: category_without_wizard.id, category: category_without_wizard.id,
title: 'Another valid and sufficiently long title for testing', title: "Another valid and sufficiently long title for testing",
raw: 'This is the body of a valid topic' raw: "This is the body of a valid topic",
) ),
) )
end.not_to raise_error end.not_to raise_error
end end

Datei anzeigen

@ -3,12 +3,10 @@
describe CustomWizardUsersController, type: :request do describe CustomWizardUsersController, type: :request do
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
before do before { @controller = UsersController.new }
@controller = UsersController.new
end
it "redirects a user to wizard after sign up if after signup is enabled" do it "redirects a user to wizard after sign up if after signup is enabled" do
template['after_signup'] = true template["after_signup"] = true
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
sign_in(Fabricate(:user)) sign_in(Fabricate(:user))
get "/u/account-created" get "/u/account-created"

Datei anzeigen

@ -5,32 +5,32 @@ module DiscourseSubscriptionClient
end end
end end
SubscriptionClientSupplier = Class.new Object do SubscriptionClientSupplier =
attr_reader :product_slugs Class.new Object do
attr_reader :product_slugs
def initialize(product_slugs) def initialize(product_slugs)
@product_slugs = product_slugs @product_slugs = product_slugs
end
end end
end
SubscriptionClientResource = Class.new Object do SubscriptionClientResource =
end Class.new Object do
end
SubscriptionClientSubscription = Class.new Object do
attr_reader :product_id SubscriptionClientSubscription =
Class.new Object do
def initialize(product_id) attr_reader :product_id
@product_id = product_id
def initialize(product_id)
@product_id = product_id
end
end end
end
module DiscourseSubscriptionClient module DiscourseSubscriptionClient
class Subscriptions class Subscriptions
class Result class Result
attr_accessor :supplier, attr_accessor :supplier, :resource, :subscriptions, :products
:resource,
:subscriptions,
:products
def any? def any?
supplier.present? && resource.present? && subscriptions.present? && products.present? supplier.present? && resource.present? && subscriptions.present? && products.present?

Datei anzeigen

@ -16,16 +16,14 @@ describe Jobs::SetAfterTimeWizard do
end end
it "sets wizard redirect for all users " do it "sets wizard redirect for all users " do
messages = MessageBus.track_publish("/redirect_to_wizard") do messages =
described_class.new.execute(wizard_id: 'super_mega_fun_wizard') MessageBus.track_publish("/redirect_to_wizard") do
end described_class.new.execute(wizard_id: "super_mega_fun_wizard")
end
expect(messages.first.data).to eq("super_mega_fun_wizard") expect(messages.first.data).to eq("super_mega_fun_wizard")
expect(messages.first.user_ids).to match_array([user1.id, user2.id, user3.id]) expect(messages.first.user_ids).to match_array([user1.id, user2.id, user3.id])
expect( expect(
UserCustomField.where( UserCustomField.where(name: "redirect_to_wizard", value: "super_mega_fun_wizard").length,
name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard'
).length
).to eq(3) ).to eq(3)
end end
@ -37,16 +35,14 @@ describe Jobs::SetAfterTimeWizard do
end end
it "only redirects users in the group" do it "only redirects users in the group" do
messages = MessageBus.track_publish("/redirect_to_wizard") do messages =
described_class.new.execute(wizard_id: 'super_mega_fun_wizard') MessageBus.track_publish("/redirect_to_wizard") do
end described_class.new.execute(wizard_id: "super_mega_fun_wizard")
end
expect(messages.first.data).to eq("super_mega_fun_wizard") expect(messages.first.data).to eq("super_mega_fun_wizard")
expect(messages.first.user_ids).to match_array([user2.id]) expect(messages.first.user_ids).to match_array([user2.id])
expect( expect(
UserCustomField.where( UserCustomField.where(name: "redirect_to_wizard", value: "super_mega_fun_wizard").length,
name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard'
).length
).to eq(1) ).to eq(1)
end end
end end
@ -58,22 +54,20 @@ describe Jobs::SetAfterTimeWizard do
action: CustomWizard::UserHistory.actions[:step], action: CustomWizard::UserHistory.actions[:step],
actor_id: user1.id, actor_id: user1.id,
context: @after_time_template[:id], context: @after_time_template[:id],
subject: step[:id] subject: step[:id],
) )
end end
end end
it "does not redirect to user" do it "does not redirect to user" do
messages = MessageBus.track_publish("/redirect_to_wizard") do messages =
described_class.new.execute(wizard_id: 'super_mega_fun_wizard') MessageBus.track_publish("/redirect_to_wizard") do
end described_class.new.execute(wizard_id: "super_mega_fun_wizard")
end
expect(messages.first.data).to eq("super_mega_fun_wizard") expect(messages.first.data).to eq("super_mega_fun_wizard")
expect(messages.first.user_ids).to match_array([user2.id, user3.id]) expect(messages.first.user_ids).to match_array([user2.id, user3.id])
expect( expect(
UserCustomField.where( UserCustomField.where(name: "redirect_to_wizard", value: "super_mega_fun_wizard").length,
name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard'
).length
).to eq(2) ).to eq(2)
end end
end end

Datei anzeigen

@ -2,9 +2,7 @@
def get_wizard_fixture(path) def get_wizard_fixture(path)
JSON.parse( JSON.parse(
File.open( File.open("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/#{path}.json").read,
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/#{path}.json"
).read
).with_indifferent_access ).with_indifferent_access
end end
@ -14,11 +12,7 @@ def enable_subscription(type)
end end
def disable_subscriptions def disable_subscriptions
%w[ %w[standard business community].each do |type|
standard
business
community
].each do |type|
CustomWizard::Subscription.stubs("#{type}?".to_sym).returns(false) CustomWizard::Subscription.stubs("#{type}?".to_sym).returns(false)
CustomWizard::Subscription.any_instance.stubs("#{type}?".to_sym).returns(false) CustomWizard::Subscription.any_instance.stubs("#{type}?".to_sym).returns(false)
end end

Datei anzeigen

@ -4,9 +4,7 @@ describe CustomWizard::AdminApiController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:api_json) { get_wizard_fixture("api/api") } let(:api_json) { get_wizard_fixture("api/api") }
before do before { sign_in(admin_user) }
sign_in(admin_user)
end
it "does not save if user does not have relevant subscription" do it "does not save if user does not have relevant subscription" do
disable_subscriptions disable_subscriptions

Datei anzeigen

@ -5,7 +5,7 @@ describe CustomWizard::AdminCustomFieldsController do
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
sign_in(admin_user) sign_in(admin_user)
@ -17,25 +17,19 @@ describe CustomWizard::AdminCustomFieldsController do
end end
it "saves custom fields" do it "saves custom fields" do
topic_field = CustomWizard::CustomField.find_by_name('topic_field_1') topic_field = CustomWizard::CustomField.find_by_name("topic_field_1")
topic_field_json = topic_field.as_json topic_field_json = topic_field.as_json
topic_field_json['type'] = 'string' topic_field_json["type"] = "string"
put "/admin/wizards/custom-fields.json", params: { put "/admin/wizards/custom-fields.json", params: { custom_field: topic_field_json }
custom_field: topic_field_json
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect( expect(CustomWizard::CustomField.find_by_name("topic_field_1").type).to eq("string")
CustomWizard::CustomField.find_by_name('topic_field_1').type
).to eq('string')
end end
it "destroys custom fields" do it "destroys custom fields" do
topic_field = custom_field_json['custom_fields'][0] topic_field = custom_field_json["custom_fields"][0]
delete "/admin/wizards/custom-fields/#{topic_field["name"]}.json" delete "/admin/wizards/custom-fields/#{topic_field["name"]}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect( expect(CustomWizard::CustomField.exists?("topic_field_1")).to eq(false)
CustomWizard::CustomField.exists?('topic_field_1')
).to eq(false)
end end
end end

Datei anzeigen

@ -5,11 +5,16 @@ describe CustomWizard::AdminLogsController do
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
before do before do
["first", "second", "third"].each_with_index do |key, index| %w[first second third].each_with_index do |key, index|
temp = template.dup temp = template.dup
temp["id"] = "#{key}_test_wizard" temp["id"] = "#{key}_test_wizard"
CustomWizard::Template.save(temp, skip_jobs: true) CustomWizard::Template.save(temp, skip_jobs: true)
CustomWizard::Log.create("#{key}_test_wizard", "perform_#{key}_action", "#{key}_test_user", "#{key} log message") CustomWizard::Log.create(
"#{key}_test_wizard",
"perform_#{key}_action",
"#{key}_test_user",
"#{key} log message",
)
end end
sign_in(admin_user) sign_in(admin_user)
end end
@ -21,21 +26,21 @@ describe CustomWizard::AdminLogsController do
it "returns a list of logs for a wizard" do it "returns a list of logs for a wizard" do
get "/admin/wizards/logs/first_test_wizard.json" get "/admin/wizards/logs/first_test_wizard.json"
expect(response.parsed_body['logs'].length).to eq(1) expect(response.parsed_body["logs"].length).to eq(1)
end end
it "paginates" do it "paginates" do
get "/admin/wizards/logs/first_test_wizard.json", params: { page: 1 } get "/admin/wizards/logs/first_test_wizard.json", params: { page: 1 }
expect(response.parsed_body['logs'].length).to eq(0) expect(response.parsed_body["logs"].length).to eq(0)
end end
it "returns total logs for a wizard" do it "returns total logs for a wizard" do
get "/admin/wizards/logs/first_test_wizard.json" get "/admin/wizards/logs/first_test_wizard.json"
expect(response.parsed_body['total']).to eq(1) expect(response.parsed_body["total"]).to eq(1)
end end
it "returns basic wizard" do it "returns basic wizard" do
get "/admin/wizards/logs/first_test_wizard.json" get "/admin/wizards/logs/first_test_wizard.json"
expect(response.parsed_body['wizard']['id']).to eq("first_test_wizard") expect(response.parsed_body["wizard"]["id"]).to eq("first_test_wizard")
end end
end end

Datei anzeigen

@ -8,28 +8,23 @@ describe CustomWizard::AdminManagerController do
sign_in(admin_user) sign_in(admin_user)
template_2 = template.dup template_2 = template.dup
template_2["id"] = 'super_mega_fun_wizard_2' template_2["id"] = "super_mega_fun_wizard_2"
template_3 = template.dup template_3 = template.dup
template_3["id"] = 'super_mega_fun_wizard_3' template_3["id"] = "super_mega_fun_wizard_3"
@template_array = [template, template_2, template_3] @template_array = [template, template_2, template_3]
FileUtils.mkdir_p(concurrency_safe_tmp_dir) unless Dir.exist?(concurrency_safe_tmp_dir) FileUtils.mkdir_p(concurrency_safe_tmp_dir) unless Dir.exist?(concurrency_safe_tmp_dir)
@tmp_file_path = File.join(concurrency_safe_tmp_dir, SecureRandom.hex << 'wizards.json') @tmp_file_path = File.join(concurrency_safe_tmp_dir, SecureRandom.hex << "wizards.json")
File.write(@tmp_file_path, @template_array.to_json) File.write(@tmp_file_path, @template_array.to_json)
end end
it 'exports all the wizard templates' do it "exports all the wizard templates" do
@template_array.each do |template| @template_array.each { |template| CustomWizard::Template.save(template, skip_jobs: true) }
CustomWizard::Template.save(template, skip_jobs: true)
end
get '/admin/wizards/manager/export.json', params: { get "/admin/wizards/manager/export.json",
wizard_ids: [ params: {
'super_mega_fun_wizard', wizard_ids: %w[super_mega_fun_wizard super_mega_fun_wizard_2 super_mega_fun_wizard_3],
'super_mega_fun_wizard_2', }
'super_mega_fun_wizard_3'
]
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body).to match_array(@template_array) expect(response.parsed_body).to match_array(@template_array)
@ -37,60 +32,60 @@ describe CustomWizard::AdminManagerController do
context "import" do context "import" do
it "works" do it "works" do
templates = @template_array.map { |t| t.slice('id', 'name') } templates = @template_array.map { |t| t.slice("id", "name") }
post '/admin/wizards/manager/import.json', params: { post "/admin/wizards/manager/import.json",
file: fixture_file_upload(File.open(@tmp_file_path)) params: {
} file: fixture_file_upload(File.open(@tmp_file_path)),
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['imported']).to match_array(templates) expect(response.parsed_body["imported"]).to match_array(templates)
expect(CustomWizard::Template.list.map { |t| t.slice('id', 'name') }).to match_array(templates) expect(CustomWizard::Template.list.map { |t| t.slice("id", "name") }).to match_array(
templates,
)
end end
it 'rejects a template with the same id as a saved template' do it "rejects a template with the same id as a saved template" do
templates = @template_array.map { |t| t.slice('id', 'name') } templates = @template_array.map { |t| t.slice("id", "name") }
post '/admin/wizards/manager/import.json', params: { post "/admin/wizards/manager/import.json",
file: fixture_file_upload(File.open(@tmp_file_path)) params: {
} file: fixture_file_upload(File.open(@tmp_file_path)),
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['imported']).to match_array(templates) expect(response.parsed_body["imported"]).to match_array(templates)
post '/admin/wizards/manager/import.json', params: { post "/admin/wizards/manager/import.json",
file: fixture_file_upload(File.open(@tmp_file_path)) params: {
} file: fixture_file_upload(File.open(@tmp_file_path)),
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['failures']).to match_array( expect(response.parsed_body["failures"]).to match_array(
@template_array.map do |t| @template_array.map do |t|
{ {
id: t['id'], id: t["id"],
messages: I18n.t("wizard.validation.conflict", wizard_id: t['id']) messages: I18n.t("wizard.validation.conflict", wizard_id: t["id"]),
}.as_json }.as_json
end end,
) )
end end
end end
it 'destroys wizard templates' do it "destroys wizard templates" do
templates = @template_array.map { |t| t.slice('id', 'name') } templates = @template_array.map { |t| t.slice("id", "name") }
@template_array.each do |template| @template_array.each { |template| CustomWizard::Template.save(template, skip_jobs: true) }
CustomWizard::Template.save(template, skip_jobs: true)
end
delete '/admin/wizards/manager/destroy.json', params: { delete "/admin/wizards/manager/destroy.json",
wizard_ids: [ params: {
'super_mega_fun_wizard', wizard_ids: %w[super_mega_fun_wizard super_mega_fun_wizard_2 super_mega_fun_wizard_3],
'super_mega_fun_wizard_2', }
'super_mega_fun_wizard_3'
]
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['destroyed']).to match_array(templates) expect(response.parsed_body["destroyed"]).to match_array(templates)
expect(CustomWizard::Template.list.length).to eq(0) expect(CustomWizard::Template.list.length).to eq(0)
end end
end end

Datei anzeigen

@ -9,26 +9,22 @@ describe CustomWizard::SubscriptionController do
end end
context "with an admin" do context "with an admin" do
before do before { sign_in(admin_user) }
sign_in(admin_user)
end
context "without a subscription" do context "without a subscription" do
before do before { disable_subscriptions }
disable_subscriptions
end
it "returns the right subscription details" do it "returns the right subscription details" do
get "/admin/wizards/subscription.json" get "/admin/wizards/subscription.json"
expect(response.parsed_body["subscribed"]).to eq(false) expect(response.parsed_body["subscribed"]).to eq(false)
expect(response.parsed_body["subscription_attributes"]).to eq(CustomWizard::Subscription.attributes.as_json) expect(response.parsed_body["subscription_attributes"]).to eq(
CustomWizard::Subscription.attributes.as_json,
)
end end
end end
context "with a subscription" do context "with a subscription" do
before do before { enable_subscription("standard") }
enable_subscription("standard")
end
it "returns the right subscription details" do it "returns the right subscription details" do
get "/admin/wizards/subscription.json" get "/admin/wizards/subscription.json"

Datei anzeigen

@ -5,18 +5,25 @@ describe CustomWizard::AdminWizardController do
fab!(:user1) { Fabricate(:user) } fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
let(:category) { Fabricate(:category, custom_fields: { create_topic_wizard: template['name'].parameterize(separator: "_") }) } let(:category) do
Fabricate(
:category,
custom_fields: {
create_topic_wizard: template["name"].parameterize(separator: "_"),
},
)
end
before do before do
enable_subscription("standard") enable_subscription("standard")
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
template_2 = template.dup template_2 = template.dup
template_2["id"] = 'super_mega_fun_wizard_2' template_2["id"] = "super_mega_fun_wizard_2"
template_2["permitted"] = template_2['permitted'] template_2["permitted"] = template_2["permitted"]
CustomWizard::Template.save(template_2, skip_jobs: true) CustomWizard::Template.save(template_2, skip_jobs: true)
template_3 = template.dup template_3 = template.dup
template_3["id"] = 'super_mega_fun_wizard_3' template_3["id"] = "super_mega_fun_wizard_3"
template_3["after_signup"] = true template_3["after_signup"] = true
CustomWizard::Template.save(template_3, skip_jobs: true) CustomWizard::Template.save(template_3, skip_jobs: true)
@ -25,40 +32,51 @@ describe CustomWizard::AdminWizardController do
it "returns a basic list of wizard templates and wizard field types" do it "returns a basic list of wizard templates and wizard field types" do
get "/admin/wizards/wizard.json" get "/admin/wizards/wizard.json"
expect( expect(response.parsed_body["wizard_list"].map { |w| w["id"] }).to match_array(
response.parsed_body['wizard_list'].map { |w| w['id'] } %w[super_mega_fun_wizard super_mega_fun_wizard_2 super_mega_fun_wizard_3],
).to match_array(['super_mega_fun_wizard', 'super_mega_fun_wizard_2', 'super_mega_fun_wizard_3']) )
expect( expect(response.parsed_body["field_types"].keys).to eq(
response.parsed_body['field_types'].keys CustomWizard::Field.types.keys.map(&:to_s),
).to eq(CustomWizard::Field.types.keys.map(&:to_s)) )
end end
it "returns a wizard template" do it "returns a wizard template" do
get "/admin/wizards/wizard/#{template['id']}.json" get "/admin/wizards/wizard/#{template["id"]}.json"
expect(response.parsed_body['id']).to eq(template['id']) expect(response.parsed_body["id"]).to eq(template["id"])
expect(response.parsed_body['steps'].length).to eq(3) expect(response.parsed_body["steps"].length).to eq(3)
end end
it "removes wizard templates whilst making sure create_topic_wizard settings for that wizard are removed from Categories" do it "removes wizard templates whilst making sure create_topic_wizard settings for that wizard are removed from Categories" do
expect(CategoryCustomField.find_by(category_id: category.id, name: 'create_topic_wizard', value: template['name'].parameterize(separator: "_"))).not_to eq(nil) expect(
delete "/admin/wizards/wizard/#{template['id']}.json" CategoryCustomField.find_by(
category_id: category.id,
name: "create_topic_wizard",
value: template["name"].parameterize(separator: "_"),
),
).not_to eq(nil)
delete "/admin/wizards/wizard/#{template["id"]}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(CustomWizard::Template.exists?(template['id'])).to eq(false) expect(CustomWizard::Template.exists?(template["id"])).to eq(false)
expect(CategoryCustomField.find_by(name: 'create_topic_wizard', value: template['name'].parameterize(separator: "_"))).to eq(nil) expect(
CategoryCustomField.find_by(
name: "create_topic_wizard",
value: template["name"].parameterize(separator: "_"),
),
).to eq(nil)
end end
it "saves wizard templates" do it "saves wizard templates" do
template_updated = template.dup template_updated = template.dup
template_updated['name'] = "Super Mega Fun Wizard 2" template_updated["name"] = "Super Mega Fun Wizard 2"
template_updated['multiple_submissions'] = false template_updated["multiple_submissions"] = false
template_updated['steps'][0]['fields'][0]['label'] = "Text 2" template_updated["steps"][0]["fields"][0]["label"] = "Text 2"
put "/admin/wizards/wizard/#{template['id']}.json", params: { wizard: template_updated } put "/admin/wizards/wizard/#{template["id"]}.json", params: { wizard: template_updated }
expect(response.status).to eq(200) expect(response.status).to eq(200)
updated_template = CustomWizard::Template.find('super_mega_fun_wizard') updated_template = CustomWizard::Template.find("super_mega_fun_wizard")
expect(updated_template['name']).to eq("Super Mega Fun Wizard 2") expect(updated_template["name"]).to eq("Super Mega Fun Wizard 2")
expect(updated_template['multiple_submissions']).to eq("false") expect(updated_template["multiple_submissions"]).to eq("false")
expect(updated_template['steps'][0]['fields'][0]['label']).to eq("Text 2") expect(updated_template["steps"][0]["fields"][0]["label"]).to eq("Text 2")
end end
end end

Datei anzeigen

@ -1,23 +1,23 @@
# frozen_string_literal: true # frozen_string_literal: true
describe ApplicationController do describe ApplicationController do
fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) } fab!(:user) do
Fabricate(:user, username: "angus", email: "angus@email.com", trust_level: TrustLevel[3])
end
let(:wizard_template) { get_wizard_fixture("wizard") } let(:wizard_template) { get_wizard_fixture("wizard") }
let(:permitted_json) { get_wizard_fixture("wizard/permitted") } let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
before do before do
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find("super_mega_fun_wizard")
end end
context "with signed in user" do context "with signed in user" do
before do before { sign_in(user) }
sign_in(user)
end
context "who is required to complete wizard" do context "who is required to complete wizard" do
before do before do
user.custom_fields['redirect_to_wizard'] = 'super_mega_fun_wizard' user.custom_fields["redirect_to_wizard"] = "super_mega_fun_wizard"
user.save_custom_fields(true) user.save_custom_fields(true)
end end
@ -55,10 +55,9 @@ describe ApplicationController do
end end
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.create(@template['id'], user).submissions CustomWizard::Wizard.create(@template["id"], user).submissions.first.redirect_to,
.first.redirect_to
).to eq("/t/2") ).to eq("/t/2")
end end
end end
@ -101,9 +100,7 @@ describe ApplicationController do
end end
context "when user is not in permitted group" do context "when user is not in permitted group" do
before do before { Group.find(13).remove(user) }
Group.find(13).remove(user)
end
it "does not redirect user" do it "does not redirect user" do
travel_to Time.now + 4.hours travel_to Time.now + 4.hours
@ -131,7 +128,7 @@ describe ApplicationController do
action: CustomWizard::UserHistory.actions[:step], action: CustomWizard::UserHistory.actions[:step],
actor_id: user.id, actor_id: user.id,
context: @template[:id], context: @template[:id],
subject: step[:id] subject: step[:id],
) )
end end
end end

Datei anzeigen

@ -7,10 +7,12 @@ describe "custom field extensions" do
let!(:user) { Fabricate(:user) } let!(:user) { Fabricate(:user) }
let!(:group) { Fabricate(:group, users: [user]) } let!(:group) { Fabricate(:group, users: [user]) }
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
let(:subscription_custom_field_json) { get_wizard_fixture("custom_field/subscription_custom_fields") } let(:subscription_custom_field_json) do
get_wizard_fixture("custom_field/subscription_custom_fields")
end
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save
end end
@ -33,13 +35,13 @@ describe "custom field extensions" do
get "/posts/#{post.id}.json" get "/posts/#{post.id}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['post_field_1']).to eq(7) expect(response.parsed_body["post_field_1"]).to eq(7)
end end
context "with a subscription" do context "with a subscription" do
before do before do
enable_subscription("business") enable_subscription("business")
subscription_custom_field_json['custom_fields'].each do |field_json| subscription_custom_field_json["custom_fields"].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save
end end
@ -63,7 +65,7 @@ describe "custom field extensions" do
get "/groups/#{group.name}.json" get "/groups/#{group.name}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['group']['group_field_1']).to eq("Group cf entry") expect(response.parsed_body["group"]["group_field_1"]).to eq("Group cf entry")
end end
context "preloaded" do context "preloaded" do
@ -76,7 +78,8 @@ describe "custom field extensions" do
get "/site.json" get "/site.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
site_category = response.parsed_body['categories'].select { |c| c['id'] == category.id }.first site_category =
response.parsed_body["categories"].select { |c| c["id"] == category.id }.first
expect(site_category["category_field_1"]).to eq({ a: 1, b: 2 }.as_json) expect(site_category["category_field_1"]).to eq({ a: 1, b: 2 }.as_json)
end end
@ -90,8 +93,8 @@ describe "custom field extensions" do
get "/groups.json" get "/groups.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
group = response.parsed_body['groups'].select { |g| g['id'] == group.id }.first group = response.parsed_body["groups"].select { |g| g["id"] == group.id }.first
expect(group['group_field_1']).to eq("Group cf entry") expect(group["group_field_1"]).to eq("Group cf entry")
end end
end end
end end

Datei anzeigen

@ -1,16 +1,11 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::RealtimeValidationsController do describe CustomWizard::RealtimeValidationsController do
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:validation_type) { "test_stub" } let(:validation_type) { "test_stub" }
let(:validation_type_stub) { let(:validation_type_stub) do
{ { types: [:text], component: "similar-topics-validator", backend: true, required_params: [] }
types: [:text], end
component: "similar-topics-validator",
backend: true,
required_params: []
}
}
before do before do
sign_in(user) sign_in(user)
@ -24,7 +19,7 @@ describe CustomWizard::RealtimeValidationsController do
def perform(params) def perform(params)
result = CustomWizard::RealtimeValidation::Result.new(:test_stub) result = CustomWizard::RealtimeValidation::Result.new(:test_stub)
result.items = ["hello", "world"] result.items = %w[hello world]
result result
end end
end end
@ -40,25 +35,22 @@ describe CustomWizard::RealtimeValidationsController do
it "gives the correct response for a given type" do it "gives the correct response for a given type" do
CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub } CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub }
get '/realtime-validations.json', params: { type: validation_type } get "/realtime-validations.json", params: { type: validation_type }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expected_response = [ expected_response = [{ "item" => "hello" }, { "item" => "world" }]
{ "item" => "hello" },
{ "item" => "world" }
]
expect(JSON.parse(response.body)).to eq(expected_response) expect(JSON.parse(response.body)).to eq(expected_response)
end end
it "gives 400 error when no type is passed" do it "gives 400 error when no type is passed" do
CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub } CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub }
get '/realtime-validations.json' get "/realtime-validations.json"
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "gives 400 error when a required additional param is missing" do it "gives 400 error when a required additional param is missing" do
CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub } CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub }
CustomWizard::RealtimeValidation.types[:test_stub][:required_params] = [:test1] CustomWizard::RealtimeValidation.types[:test_stub][:required_params] = [:test1]
get '/realtime-validations.json', params: { type: validation_type } get "/realtime-validations.json", params: { type: validation_type }
expect(response.status).to eq(400) expect(response.status).to eq(400)
# the addition is only relevant to this test, so getting rid of it # the addition is only relevant to this test, so getting rid of it
CustomWizard::RealtimeValidation.types[:test_stub][:required_params] = [] CustomWizard::RealtimeValidation.types[:test_stub][:required_params] = []
@ -66,7 +58,7 @@ describe CustomWizard::RealtimeValidationsController do
it "gives 500 response code when a non existant type is passed" do it "gives 500 response code when a non existant type is passed" do
CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub } CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub }
get '/realtime-validations.json', params: { type: "random_type" } get "/realtime-validations.json", params: { type: "random_type" }
expect(response.status).to eq(500) expect(response.status).to eq(500)
end end
end end

Datei anzeigen

@ -1,8 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::StepsController do describe CustomWizard::StepsController do
fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) } fab!(:user) do
fab!(:user2) { Fabricate(:user, username: 'bob', email: "bob@email.com", trust_level: TrustLevel[2]) } Fabricate(:user, username: "angus", email: "angus@email.com", trust_level: TrustLevel[3])
end
fab!(:user2) do
Fabricate(:user, username: "bob", email: "bob@email.com", trust_level: TrustLevel[2])
end
let(:wizard_template) { get_wizard_fixture("wizard") } let(:wizard_template) { get_wizard_fixture("wizard") }
let(:wizard_field_condition_template) { get_wizard_fixture("condition/wizard_field_condition") } let(:wizard_field_condition_template) { get_wizard_fixture("condition/wizard_field_condition") }
let(:user_condition_template) { get_wizard_fixture("condition/user_condition") } let(:user_condition_template) { get_wizard_fixture("condition/user_condition") }
@ -11,9 +15,7 @@ describe CustomWizard::StepsController do
let(:route_to_template) { get_wizard_fixture("actions/route_to") } let(:route_to_template) { get_wizard_fixture("actions/route_to") }
let(:guests_permitted) { get_wizard_fixture("wizard/guests_permitted") } let(:guests_permitted) { get_wizard_fixture("wizard/guests_permitted") }
before do before { CustomWizard::Template.save(wizard_template, skip_jobs: true) }
CustomWizard::Template.save(wizard_template, skip_jobs: true)
end
def guest_template def guest_template
temp = wizard_template.dup temp = wizard_template.dup
@ -25,11 +27,12 @@ describe CustomWizard::StepsController do
context "with guest" do context "with guest" do
it "does not perform a step update" do it "does not perform a step update" do
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Text input" fields: {
} step_1_field_1: "Text input",
} },
}
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
@ -40,22 +43,23 @@ describe CustomWizard::StepsController do
end end
it "performs a step update" do it "performs a step update" do
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Text input" fields: {
} step_1_field_1: "Text input",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
wizard_id = response.parsed_body['wizard']['id'] wizard_id = response.parsed_body["wizard"]["id"]
wizard = CustomWizard::Wizard.create(wizard_id, nil, cookies[:custom_wizard_guest_id]) wizard = CustomWizard::Wizard.create(wizard_id, nil, cookies[:custom_wizard_guest_id])
expect(wizard.current_submission.fields['step_1_field_1']).to eq("Text input") expect(wizard.current_submission.fields["step_1_field_1"]).to eq("Text input")
end end
context "raises an error" do context "raises an error" do
it "when the wizard doesnt exist" do it "when the wizard doesnt exist" do
put '/w/not-super-mega-fun-wizard/steps/step_1.json' put "/w/not-super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
@ -65,74 +69,74 @@ describe CustomWizard::StepsController do
new_template["permitted"] = permitted_json["permitted"] new_template["permitted"] = permitted_json["permitted"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
it "when the step doesnt exist" do it "when the step doesnt exist" do
put '/w/super-mega-fun-wizard/steps/step_10.json' put "/w/super-mega-fun-wizard/steps/step_10.json"
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
end end
it "works if the step has no fields" do it "works if the step has no fields" do
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
end end
it "returns an updated wizard when condition passes" do it "returns an updated wizard when condition passes" do
new_template = guest_template.dup new_template = guest_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][1]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will pass" fields: {
} step_1_field_1: "Condition will pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
end end
it "runs completion actions if guest has completed wizard" do it "runs completion actions if guest has completed wizard" do
new_template = guest_template.dup new_template = guest_template.dup
## route_to action ## route_to action
new_template['actions'].last['run_after'] = 'wizard_completion' new_template["actions"].last["run_after"] = "wizard_completion"
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
put '/w/super-mega-fun-wizard/steps/step_2.json' put "/w/super-mega-fun-wizard/steps/step_2.json"
put '/w/super-mega-fun-wizard/steps/step_3.json' put "/w/super-mega-fun-wizard/steps/step_3.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['redirect_on_complete']).to eq("https://google.com") expect(response.parsed_body["redirect_on_complete"]).to eq("https://google.com")
end end
end end
end end
context "with user" do context "with user" do
before do before { sign_in(user) }
sign_in(user)
end
it 'performs a step update' do it "performs a step update" do
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Text input" fields: {
} step_1_field_1: "Text input",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
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)
expect(wizard.current_submission.fields['step_1_field_1']).to eq("Text input") expect(wizard.current_submission.fields["step_1_field_1"]).to eq("Text input")
end end
context "raises an error" do context "raises an error" do
it "when the wizard doesnt exist" do it "when the wizard doesnt exist" do
put '/w/not-super-mega-fun-wizard/steps/step_1.json' put "/w/not-super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
@ -142,120 +146,121 @@ describe CustomWizard::StepsController do
new_template["permitted"] = admin_permitted_json["permitted"] new_template["permitted"] = admin_permitted_json["permitted"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
it "when the step doesnt exist" do it "when the step doesnt exist" do
put '/w/super-mega-fun-wizard/steps/step_10.json' put "/w/super-mega-fun-wizard/steps/step_10.json"
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
end end
it "works if the step has no fields" do it "works if the step has no fields" do
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
end end
it "returns an updated wizard when condition passes" do it "returns an updated wizard when condition passes" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][1]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will pass" fields: {
} step_1_field_1: "Condition will pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
end end
it "runs completion actions if user has completed wizard" do it "runs completion actions if user has completed wizard" do
new_template = wizard_template.dup new_template = wizard_template.dup
## route_to action ## route_to action
new_template['actions'].last['run_after'] = 'wizard_completion' new_template["actions"].last["run_after"] = "wizard_completion"
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
put '/w/super-mega-fun-wizard/steps/step_2.json' put "/w/super-mega-fun-wizard/steps/step_2.json"
put '/w/super-mega-fun-wizard/steps/step_3.json' put "/w/super-mega-fun-wizard/steps/step_3.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['redirect_on_complete']).to eq("https://google.com") expect(response.parsed_body["redirect_on_complete"]).to eq("https://google.com")
end end
it "saves results of completion actions if user has completed wizard" do it "saves results of completion actions if user has completed wizard" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['actions'].first['run_after'] = 'wizard_completion' new_template["actions"].first["run_after"] = "wizard_completion"
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Topic title", fields: {
step_1_field_2: "Topic post" step_1_field_1: "Topic title",
} step_1_field_2: "Topic post",
} },
put '/w/super-mega-fun-wizard/steps/step_2.json' }
put '/w/super-mega-fun-wizard/steps/step_3.json' put "/w/super-mega-fun-wizard/steps/step_2.json"
put "/w/super-mega-fun-wizard/steps/step_3.json"
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)
topic_id = wizard.submissions.first.fields[new_template['actions'].first['id']] topic_id = wizard.submissions.first.fields[new_template["actions"].first["id"]]
topic = Topic.find(topic_id) topic = Topic.find(topic_id)
expect(topic.present?).to eq(true) expect(topic.present?).to eq(true)
end end
it "returns a final step without conditions" do it "returns a final step without conditions" do
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(false) expect(response.parsed_body["final"]).to eq(false)
put '/w/super-mega-fun-wizard/steps/step_2.json' put "/w/super-mega-fun-wizard/steps/step_2.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(false) expect(response.parsed_body["final"]).to eq(false)
put '/w/super-mega-fun-wizard/steps/step_3.json' put "/w/super-mega-fun-wizard/steps/step_3.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(true) expect(response.parsed_body["final"]).to eq(true)
end end
context "subscription" do context "subscription" do
before do before { enable_subscription("standard") }
enable_subscription("standard")
end
it "raises an error when user cant see the step due to conditions" do it "raises an error when user cant see the step due to conditions" do
sign_in(user2) sign_in(user2)
new_wizard_template = wizard_template.dup new_wizard_template = wizard_template.dup
new_wizard_template['steps'][0]['condition'] = user_condition_template['condition'] new_wizard_template["steps"][0]["condition"] = user_condition_template["condition"]
CustomWizard::Template.save(new_wizard_template, skip_jobs: true) CustomWizard::Template.save(new_wizard_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
it "returns an updated wizard when condition doesnt pass" do it "returns an updated wizard when condition doesnt pass" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][1]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition wont pass" fields: {
} step_1_field_1: "Condition wont pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_3") expect(response.parsed_body["wizard"]["start"]).to eq("step_3")
end end
it "returns the correct final step when the conditional final step and last step are the same" do it "returns the correct final step when the conditional final step and last step are the same" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][0]['condition'] = user_condition_template['condition'] new_template["steps"][0]["condition"] = user_condition_template["condition"]
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][2]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
end end
@ -263,107 +268,116 @@ describe CustomWizard::StepsController do
sign_in(user2) sign_in(user2)
new_wizard_template = wizard_template.dup new_wizard_template = wizard_template.dup
new_wizard_template['steps'][0]['condition'] = user_condition_template['condition'] new_wizard_template["steps"][0]["condition"] = user_condition_template["condition"]
CustomWizard::Template.save(new_wizard_template, skip_jobs: true) CustomWizard::Template.save(new_wizard_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json' put "/w/super-mega-fun-wizard/steps/step_1.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
it "returns an updated wizard when condition doesnt pass" do it "returns an updated wizard when condition doesnt pass" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][1]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition wont pass" fields: {
} step_1_field_1: "Condition wont pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_3") expect(response.parsed_body["wizard"]["start"]).to eq("step_3")
end end
it "returns the correct final step when the conditional final step and last step are the same" do it "returns the correct final step when the conditional final step and last step are the same" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][0]['condition'] = user_condition_template['condition'] new_template["steps"][0]["condition"] = user_condition_template["condition"]
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][2]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will pass" fields: {
} step_1_field_1: "Condition will pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(false) expect(response.parsed_body["final"]).to eq(false)
put '/w/super-mega-fun-wizard/steps/step_2.json' put "/w/super-mega-fun-wizard/steps/step_2.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(false) expect(response.parsed_body["final"]).to eq(false)
put '/w/super-mega-fun-wizard/steps/step_3.json' put "/w/super-mega-fun-wizard/steps/step_3.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(true) expect(response.parsed_body["final"]).to eq(true)
end end
it "returns the correct final step when the conditional final step and last step are different" do it "returns the correct final step when the conditional final step and last step are different" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][2]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will not pass" fields: {
} step_1_field_1: "Condition will not pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(false) expect(response.parsed_body["final"]).to eq(false)
put '/w/super-mega-fun-wizard/steps/step_2.json' put "/w/super-mega-fun-wizard/steps/step_2.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(true) expect(response.parsed_body["final"]).to eq(true)
end end
it "returns the correct final step when the conditional final step is determined in the same action" do it "returns the correct final step when the conditional final step is determined in the same action" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][1]["condition"] = wizard_field_condition_template["condition"]
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][2]["condition"] = wizard_field_condition_template["condition"]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will not pass" fields: {
} step_1_field_1: "Condition will not pass",
} },
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(true) expect(response.parsed_body["final"]).to eq(true)
end end
it "excludes the non-included conditional fields from the submissions" do it "excludes the non-included conditional fields from the submissions" do
new_template = wizard_template.dup new_template = wizard_template.dup
new_template['steps'][1]['fields'][0]['condition'] = wizard_field_condition_template['condition'] new_template["steps"][1]["fields"][0]["condition"] = wizard_field_condition_template[
"condition"
]
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will pass" fields: {
} step_1_field_1: "Condition will pass",
} },
}
put '/w/super-mega-fun-wizard/steps/step_2.json', params: { put "/w/super-mega-fun-wizard/steps/step_2.json",
fields: { params: {
step_2_field_1: "1995-04-23" fields: {
} step_2_field_1: "1995-04-23",
} },
}
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Condition will not pass" fields: {
} step_1_field_1: "Condition will not pass",
} },
}
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)
submission = wizard.current_submission submission = wizard.current_submission
expect(submission.fields.keys).not_to include("step_2_field_1") expect(submission.fields.keys).not_to include("step_2_field_1")

Datei anzeigen

@ -1,7 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::WizardController do describe CustomWizard::WizardController do
fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) } fab!(:user) do
Fabricate(:user, username: "angus", email: "angus@email.com", trust_level: TrustLevel[3])
end
let(:wizard_template) { get_wizard_fixture("wizard") } let(:wizard_template) { get_wizard_fixture("wizard") }
let(:permitted_json) { get_wizard_fixture("wizard/permitted") } let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
@ -10,66 +12,62 @@ describe CustomWizard::WizardController do
@template = CustomWizard::Template.find("super_mega_fun_wizard") @template = CustomWizard::Template.find("super_mega_fun_wizard")
end end
context 'plugin disabled' do context "plugin disabled" do
before do before { SiteSetting.custom_wizard_enabled = false }
SiteSetting.custom_wizard_enabled = false
end
it 'redirects to root' do it "redirects to root" do
get '/w/super-mega-fun-wizard', xhr: true get "/w/super-mega-fun-wizard", xhr: true
expect(response).to redirect_to("/") expect(response).to redirect_to("/")
end end
end end
it 'returns wizard' do it "returns wizard" do
get '/w/super-mega-fun-wizard.json' get "/w/super-mega-fun-wizard.json"
expect(response.parsed_body["id"]).to eq("super_mega_fun_wizard") expect(response.parsed_body["id"]).to eq("super_mega_fun_wizard")
end end
it 'returns missing message if no wizard exists' do it "returns missing message if no wizard exists" do
get '/w/super-mega-fun-wizards.json' get "/w/super-mega-fun-wizards.json"
expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.") expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.")
end end
context "with user" do context "with user" do
before do before { sign_in(user) }
sign_in(user)
end
context 'when user skips' do context "when user skips" do
it 'skips a wizard if user is allowed to skip' do it "skips a wizard if user is allowed to skip" do
put '/w/super-mega-fun-wizard/skip.json' put "/w/super-mega-fun-wizard/skip.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
it 'lets user skip if user cant access wizard' do it "lets user skip if user cant access wizard" do
enable_subscription("standard") enable_subscription("standard")
@template["permitted"] = permitted_json["permitted"] @template["permitted"] = permitted_json["permitted"]
CustomWizard::Template.save(@template, skip_jobs: true) CustomWizard::Template.save(@template, skip_jobs: true)
put '/w/super-mega-fun-wizard/skip.json' put "/w/super-mega-fun-wizard/skip.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
it 'returns a no skip message if user is not allowed to skip' do it "returns a no skip message if user is not allowed to skip" do
enable_subscription("standard") enable_subscription("standard")
@template['required'] = 'true' @template["required"] = "true"
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
put '/w/super-mega-fun-wizard/skip.json' put "/w/super-mega-fun-wizard/skip.json"
expect(response.parsed_body['error']).to eq("Wizard can't be skipped") expect(response.parsed_body["error"]).to eq("Wizard can't be skipped")
end end
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, redirect_to: "/t/2").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
it 'deletes the users redirect_to_wizard if present' do it "deletes the users redirect_to_wizard if present" do
user.custom_fields['redirect_to_wizard'] = @template["id"] user.custom_fields["redirect_to_wizard"] = @template["id"]
user.save_custom_fields(true) user.save_custom_fields(true)
@wizard = CustomWizard::Wizard.create(@template["id"], user) @wizard = CustomWizard::Wizard.create(@template["id"], user)
put '/w/super-mega-fun-wizard/skip.json' put "/w/super-mega-fun-wizard/skip.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(user.reload.redirect_to_wizard).to eq(nil) expect(user.reload.redirect_to_wizard).to eq(nil)
end end
@ -78,22 +76,25 @@ describe CustomWizard::WizardController do
@wizard = CustomWizard::Wizard.create(@template["id"], user) @wizard = CustomWizard::Wizard.create(@template["id"], user)
CustomWizard::Submission.new(@wizard, step_1_field_1: "Hello World").save CustomWizard::Submission.new(@wizard, step_1_field_1: "Hello World").save
current_submission = @wizard.current_submission current_submission = @wizard.current_submission
put '/w/super-mega-fun-wizard/skip.json' put "/w/super-mega-fun-wizard/skip.json"
submissions = CustomWizard::Submission.list(@wizard).submissions submissions = CustomWizard::Submission.list(@wizard).submissions
expect(submissions.any? { |submission| submission.id == current_submission.id }).to eq(false) expect(submissions.any? { |submission| submission.id == current_submission.id }).to eq(
false,
)
end end
it "starts from the first step if user visits after skipping the wizard" do it "starts from the first step if user visits after skipping the wizard" do
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put "/w/super-mega-fun-wizard/steps/step_1.json",
fields: { params: {
step_1_field_1: "Text input" fields: {
} step_1_field_1: "Text input",
} },
put '/w/super-mega-fun-wizard/skip.json' }
get '/w/super-mega-fun-wizard.json' put "/w/super-mega-fun-wizard/skip.json"
get "/w/super-mega-fun-wizard.json"
expect(response.parsed_body["start"]).to eq('step_1') expect(response.parsed_body["start"]).to eq("step_1")
end end
end end
end end

Datei anzeigen

@ -1,15 +1,16 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::BasicWizardSerializer do describe CustomWizard::BasicWizardSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:template) { get_wizard_fixture("wizard") } let(:template) { get_wizard_fixture("wizard") }
it 'should return basic wizard attributes' do it "should return basic wizard attributes" do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
json = CustomWizard::BasicWizardSerializer.new( json =
CustomWizard::Builder.new("super_mega_fun_wizard", user).build, CustomWizard::BasicWizardSerializer.new(
scope: Guardian.new(user) CustomWizard::Builder.new("super_mega_fun_wizard", user).build,
).as_json scope: Guardian.new(user),
).as_json
expect(json[:basic_wizard][:id]).to eq("super_mega_fun_wizard") expect(json[:basic_wizard][:id]).to eq("super_mega_fun_wizard")
expect(json[:basic_wizard][:name]).to eq("Super Mega Fun Wizard") expect(json[:basic_wizard][:name]).to eq("Super Mega Fun Wizard")
end end

Datei anzeigen

@ -1,22 +1,23 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::CustomFieldSerializer do describe CustomWizard::CustomFieldSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user)
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
it 'should return custom field attributes' do it "should return custom field attributes" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json["custom_fields"].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
json = CustomWizard::CustomFieldSerializer.new( json =
CustomWizard::CustomField.find_by_name("topic_field_1"), CustomWizard::CustomFieldSerializer.new(
scope: Guardian.new(user), CustomWizard::CustomField.find_by_name("topic_field_1"),
root: false scope: Guardian.new(user),
).as_json root: false,
).as_json
expect(json[:name]).to eq("topic_field_1") expect(json[:name]).to eq("topic_field_1")
expect(json[:klass]).to eq("topic") expect(json[:klass]).to eq("topic")
expect(json[:type]).to eq("boolean") expect(json[:type]).to eq("boolean")
expect(json[:serializers]).to match_array(["topic_list_item", "topic_view"]) expect(json[:serializers]).to match_array(%w[topic_list_item topic_view])
end end
end end

Datei anzeigen

@ -1,19 +1,31 @@
# frozen_string_literal: true # frozen_string_literal: true
describe CustomWizard::LogSerializer do describe CustomWizard::LogSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user)
it 'should return log attributes' do it "should return log attributes" do
CustomWizard::Log.create('first-test-wizard', 'perform_first_action', 'first_test_user', 'First log message', 1.day.ago) CustomWizard::Log.create(
CustomWizard::Log.create('second-test-wizard', 'perform_second_action', 'second_test_user', 'Second log message') "first-test-wizard",
"perform_first_action",
"first_test_user",
"First log message",
1.day.ago,
)
CustomWizard::Log.create(
"second-test-wizard",
"perform_second_action",
"second_test_user",
"Second log message",
)
json_array = ActiveModel::ArraySerializer.new( json_array =
CustomWizard::Log.list(0).logs, ActiveModel::ArraySerializer.new(
each_serializer: CustomWizard::LogSerializer CustomWizard::Log.list(0).logs,
).as_json each_serializer: CustomWizard::LogSerializer,
).as_json
expect(json_array.length).to eq(2) expect(json_array.length).to eq(2)
expect(json_array[0][:action]).to eq("perform_second_action") expect(json_array[0][:action]).to eq("perform_second_action")
expect(json_array[0][:username]).to eq('second_test_user') expect(json_array[0][:username]).to eq("second_test_user")
expect(json_array[0][:message]).to eq("Second log message") expect(json_array[0][:message]).to eq("Second log message")
end end
end end

Datei anzeigen

@ -1,35 +1,41 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative '../../plugin_helper' require_relative "../../plugin_helper"
describe CustomWizard::SubmissionSerializer do describe CustomWizard::SubmissionSerializer do
fab!(:user1) { Fabricate(:user) } fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
let(:template_json) { let(:template_json) do
JSON.parse(File.open( JSON.parse(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" File.open("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json").read,
).read) )
} end
before do before do
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
wizard = CustomWizard::Wizard.create(template_json["id"], user1) wizard = CustomWizard::Wizard.create(template_json["id"], user1)
CustomWizard::Submission.new(wizard, step_1_field_1: "I am user1 submission", submitted_at: Time.now.iso8601).save CustomWizard::Submission.new(
wizard,
step_1_field_1: "I am user1 submission",
submitted_at: Time.now.iso8601,
).save
wizard = CustomWizard::Wizard.create(template_json["id"], user2) wizard = CustomWizard::Wizard.create(template_json["id"], user2)
CustomWizard::Submission.new(wizard, step_1_field_1: "I am user2 submission", submitted_at: Time.now.iso8601).save CustomWizard::Submission.new(
wizard,
step_1_field_1: "I am user2 submission",
submitted_at: Time.now.iso8601,
).save
end end
it 'should return submission attributes' do it "should return submission attributes" do
wizard = CustomWizard::Wizard.create(template_json["id"]) wizard = CustomWizard::Wizard.create(template_json["id"])
list = CustomWizard::Submission.list(wizard, page: 0, order_by: 'id') list = CustomWizard::Submission.list(wizard, page: 0, order_by: "id")
json_array = ActiveModel::ArraySerializer.new( json_array =
list.submissions, ActiveModel::ArraySerializer.new(list.submissions, each_serializer: described_class).as_json
each_serializer: described_class
).as_json
expect(json_array.length).to eq(2) expect(json_array.length).to eq(2)
expect(json_array[0][:id].present?).to eq(true) expect(json_array[0][:id].present?).to eq(true)
@ -40,20 +46,14 @@ describe CustomWizard::SubmissionSerializer do
it "should return field values, types and labels" do it "should return field values, types and labels" do
wizard = CustomWizard::Wizard.create(template_json["id"]) wizard = CustomWizard::Wizard.create(template_json["id"])
list = CustomWizard::Submission.list(wizard, page: 0, order_by: 'id') list = CustomWizard::Submission.list(wizard, page: 0, order_by: "id")
json_array = ActiveModel::ArraySerializer.new( json_array =
list.submissions, ActiveModel::ArraySerializer.new(list.submissions, each_serializer: described_class).as_json
each_serializer: described_class
).as_json
expect(json_array.length).to eq(2) expect(json_array.length).to eq(2)
expect(json_array[0][:fields].as_json).to eq({ expect(json_array[0][:fields].as_json).to eq(
"step_1_field_1": { { step_1_field_1: { value: "I am user2 submission", type: "text", label: "Text" } }.as_json,
"value": "I am user2 submission", )
"type": "text",
"label": "Text"
}
}.as_json)
end end
end end

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen