Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-25 02:30:28 +01:00
COMPATIBILITY: update linting
Dieser Commit ist enthalten in:
Ursprung
a163ba56ae
Commit
f042f6b9b8
103 geänderte Dateien mit 2736 neuen und 3210 gelöschten Zeilen
|
@ -1,5 +1,10 @@
|
|||
inherit_gem:
|
||||
rubocop-discourse: default.yml
|
||||
rubocop-discourse: stree-compat.yml
|
||||
|
||||
AllCops:
|
||||
Exclude:
|
||||
- 'gems/**/*'
|
||||
- 'vendor/**/*'
|
||||
|
||||
RSpec/ContextWording:
|
||||
Enabled: false
|
||||
|
|
2
.streerc
Normale Datei
2
.streerc
Normale Datei
|
@ -0,0 +1,2 @@
|
|||
--print-width=100
|
||||
--plugins=plugin/trailing_comma,plugin/disable_auto_ternary
|
7
Gemfile
7
Gemfile
|
@ -1,8 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
source "https://rubygems.org"
|
||||
|
||||
group :development do
|
||||
gem 'rubocop-discourse'
|
||||
gem 'racc'
|
||||
gem "rubocop-discourse"
|
||||
gem "syntax_tree"
|
||||
gem "racc"
|
||||
end
|
||||
|
|
|
@ -28,6 +28,7 @@ GEM
|
|||
parser (3.3.5.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
prettier_print (1.2.1)
|
||||
racc (1.8.1)
|
||||
rack (3.1.7)
|
||||
rainbow (3.1.1)
|
||||
|
@ -68,6 +69,8 @@ GEM
|
|||
rubocop-rspec (~> 3, >= 3.0.1)
|
||||
ruby-progressbar (1.13.0)
|
||||
securerandom (0.3.1)
|
||||
syntax_tree (6.2.0)
|
||||
prettier_print (>= 1.2.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (2.6.0)
|
||||
|
@ -79,6 +82,7 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
racc
|
||||
rubocop-discourse
|
||||
syntax_tree
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.18
|
||||
|
|
|
@ -3,21 +3,28 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
skip_before_action :check_xhr, only: [:redirect]
|
||||
|
||||
def list
|
||||
serializer = ActiveModel::ArraySerializer.new(CustomWizard::Api.list,
|
||||
each_serializer: CustomWizard::BasicApiSerializer
|
||||
serializer =
|
||||
ActiveModel::ArraySerializer.new(
|
||||
CustomWizard::Api.list,
|
||||
each_serializer: CustomWizard::BasicApiSerializer,
|
||||
)
|
||||
render json: MultiJson.dump(serializer)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def save
|
||||
current = CustomWizard::Api.get(api_params[:name])
|
||||
|
||||
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
|
||||
|
||||
unless subscription.includes?(:api, :all)
|
||||
|
@ -28,27 +35,27 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
CustomWizard::Api.set(api_params[:name], title: api_params[:title])
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
if api_params[:endpoints].is_a? String
|
||||
begin
|
||||
endpoints = JSON.parse(api_params[:endpoints])
|
||||
endpoints.each do |endpoint|
|
||||
CustomWizard::Api::Endpoint.set(api_params[:name], endpoint)
|
||||
end
|
||||
endpoints.each { |endpoint| CustomWizard::Api::Endpoint.set(api_params[:name], endpoint) }
|
||||
rescue => e
|
||||
puts e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
render json: success_json.merge(
|
||||
api: CustomWizard::ApiSerializer.new(
|
||||
render json:
|
||||
success_json.merge(
|
||||
api:
|
||||
CustomWizard::ApiSerializer.new(
|
||||
CustomWizard::Api.get(api_params[:name]),
|
||||
root: false
|
||||
)
|
||||
root: false,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -67,13 +74,15 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
result = CustomWizard::Api::Authorization.get_token(api_params[:name])
|
||||
|
||||
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
|
||||
render json: success_json.merge(
|
||||
api: CustomWizard::ApiSerializer.new(
|
||||
render json:
|
||||
success_json.merge(
|
||||
api:
|
||||
CustomWizard::ApiSerializer.new(
|
||||
CustomWizard::Api.get(api_params[:name]),
|
||||
root: false
|
||||
)
|
||||
root: false,
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -90,7 +99,7 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
CustomWizard::Api::Authorization.set(params[:name], code: params[:code])
|
||||
CustomWizard::Api::Authorization.get_token(params[:name])
|
||||
|
||||
redirect_to path('/admin/wizards/apis/' + params[:name])
|
||||
redirect_to path("/admin/wizards/apis/" + params[:name])
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -98,7 +107,8 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
def api_params
|
||||
params.require(:name)
|
||||
|
||||
data = params.permit(
|
||||
data =
|
||||
params.permit(
|
||||
:name,
|
||||
:title,
|
||||
:auth_type,
|
||||
|
@ -110,7 +120,7 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
:password,
|
||||
:auth_params,
|
||||
:endpoints,
|
||||
:new
|
||||
:new,
|
||||
).to_h
|
||||
|
||||
data[:name] = data[:name].underscore
|
||||
|
@ -119,7 +129,8 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
end
|
||||
|
||||
def auth_data
|
||||
auth_data = api_params.slice(
|
||||
auth_data =
|
||||
api_params.slice(
|
||||
:auth_type,
|
||||
:auth_url,
|
||||
:token_url,
|
||||
|
@ -127,10 +138,12 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
|
|||
:client_secret,
|
||||
:username,
|
||||
:password,
|
||||
:auth_params
|
||||
: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
|
||||
end
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
|
||||
def index
|
||||
render_json_dump(
|
||||
custom_fields: custom_field_list
|
||||
)
|
||||
render_json_dump(custom_fields: custom_field_list)
|
||||
end
|
||||
|
||||
def update
|
||||
|
@ -12,23 +10,24 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
|
|||
field_data = {}
|
||||
|
||||
if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i)
|
||||
CustomWizard::CustomField::ATTRS.each do |attr|
|
||||
field_data[attr] = saved_field.send(attr)
|
||||
end
|
||||
CustomWizard::CustomField::ATTRS.each { |attr| field_data[attr] = saved_field.send(attr) }
|
||||
field_id = saved_field.id
|
||||
end
|
||||
|
||||
CustomWizard::CustomField::ATTRS.each do |attr|
|
||||
field_data[attr] = field_params[attr]
|
||||
end
|
||||
CustomWizard::CustomField::ATTRS.each { |attr| field_data[attr] = field_params[attr] }
|
||||
|
||||
field = CustomWizard::CustomField.new(field_id, field_data)
|
||||
|
||||
PluginStoreRow.transaction do
|
||||
unless field.save
|
||||
field_errors = field.errors.any? ?
|
||||
field.errors.full_messages.join("\n\n") :
|
||||
field_errors =
|
||||
(
|
||||
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
|
||||
raise ActiveRecord::Rollback.new
|
||||
end
|
||||
|
@ -54,13 +53,6 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
|
|||
private
|
||||
|
||||
def field_params
|
||||
params.required(:custom_field)
|
||||
.permit(
|
||||
:id,
|
||||
:name,
|
||||
:klass,
|
||||
:type,
|
||||
serializers: []
|
||||
)
|
||||
params.required(:custom_field).permit(:id, :name, :klass, :type, serializers: [])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,39 +3,42 @@ class CustomWizard::AdminLogsController < CustomWizard::AdminController
|
|||
before_action :find_wizard, except: [:index]
|
||||
|
||||
def index
|
||||
render json: ActiveModel::ArraySerializer.new(
|
||||
render json:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
CustomWizard::Wizard.list(current_user),
|
||||
each_serializer: CustomWizard::BasicWizardSerializer
|
||||
each_serializer: CustomWizard::BasicWizardSerializer,
|
||||
)
|
||||
end
|
||||
|
||||
def show
|
||||
render_json_dump(
|
||||
wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false),
|
||||
logs: ActiveModel::ArraySerializer.new(
|
||||
logs:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
log_list.logs,
|
||||
each_serializer: CustomWizard::LogSerializer
|
||||
each_serializer: CustomWizard::LogSerializer,
|
||||
),
|
||||
total: log_list.total
|
||||
total: log_list.total,
|
||||
)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def log_list
|
||||
@log_list ||= begin
|
||||
@log_list ||=
|
||||
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?
|
||||
user_map = User.where(username: usernames)
|
||||
user_map =
|
||||
User
|
||||
.where(username: usernames)
|
||||
.reduce({}) do |result, user|
|
||||
result[user.username] = user
|
||||
result
|
||||
end
|
||||
|
||||
list.logs.each do |log_item|
|
||||
log_item.user = user_map[log_item.username]
|
||||
end
|
||||
list.logs.each { |log_item| log_item.user = user_map[log_item.username] }
|
||||
end
|
||||
|
||||
list
|
||||
|
|
|
@ -12,38 +12,32 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
|
|||
end
|
||||
end
|
||||
|
||||
if templates.empty?
|
||||
return render_error(I18n.t('wizard.export.error.invalid_wizards'))
|
||||
end
|
||||
return render_error(I18n.t("wizard.export.error.invalid_wizards")) if templates.empty?
|
||||
|
||||
basename = SiteSetting.title.parameterize || 'discourse'
|
||||
basename = SiteSetting.title.parameterize || "discourse"
|
||||
time = Time.now.to_i
|
||||
filename = "#{basename}-wizards-#{time}.json"
|
||||
|
||||
send_data templates.to_json,
|
||||
type: "application/json",
|
||||
disposition: 'attachment',
|
||||
disposition: "attachment",
|
||||
filename: filename
|
||||
end
|
||||
|
||||
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'))
|
||||
end
|
||||
return render_error(I18n.t("wizard.export.error.no_file")) if file.nil?
|
||||
|
||||
file_size = file.size
|
||||
max_file_size = 512 * 1024
|
||||
|
||||
if max_file_size < file_size
|
||||
return render_error(I18n.t('wizard.import.error.file_large'))
|
||||
end
|
||||
return render_error(I18n.t("wizard.import.error.file_large")) if max_file_size < file_size
|
||||
|
||||
begin
|
||||
template_json = JSON.parse(file)
|
||||
rescue JSON::ParserError
|
||||
return render_error(I18n.t('wizard.import.error.invalid_json'))
|
||||
return render_error(I18n.t("wizard.import.error.invalid_json"))
|
||||
end
|
||||
|
||||
imported = []
|
||||
|
@ -55,22 +49,13 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
|
|||
template.save(skip_jobs: true, create: true)
|
||||
|
||||
if template.errors.any?
|
||||
failures.push(
|
||||
id: template.data['id'],
|
||||
messages: template.errors.full_messages.join(', ')
|
||||
)
|
||||
failures.push(id: template.data["id"], messages: template.errors.full_messages.join(", "))
|
||||
else
|
||||
imported.push(
|
||||
id: template.data['id'],
|
||||
name: template.data['name']
|
||||
)
|
||||
imported.push(id: template.data["id"], name: template.data["name"])
|
||||
end
|
||||
end
|
||||
|
||||
render json: success_json.merge(
|
||||
imported: imported,
|
||||
failures: failures
|
||||
)
|
||||
render json: success_json.merge(imported: imported, failures: failures)
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -81,44 +66,34 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
|
|||
template = CustomWizard::Template.find(wizard_id)
|
||||
|
||||
if template && CustomWizard::Template.remove(wizard_id)
|
||||
destroyed.push(
|
||||
id: wizard_id,
|
||||
name: template['name']
|
||||
)
|
||||
destroyed.push(id: wizard_id, name: template["name"])
|
||||
else
|
||||
failures.push(
|
||||
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
|
||||
|
||||
render json: success_json.merge(
|
||||
destroyed: destroyed,
|
||||
failures: failures
|
||||
)
|
||||
render json: success_json.merge(destroyed: destroyed, failures: failures)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_wizard_ids
|
||||
if params['wizard_ids'].blank?
|
||||
return render_error(I18n.t('wizard.export.error.select_one'))
|
||||
end
|
||||
return render_error(I18n.t("wizard.export.error.select_one")) if params["wizard_ids"].blank?
|
||||
|
||||
wizard_ids = []
|
||||
|
||||
params['wizard_ids'].each do |wizard_id|
|
||||
params["wizard_ids"].each do |wizard_id|
|
||||
begin
|
||||
wizard_ids.push(wizard_id.underscore)
|
||||
rescue
|
||||
rescue StandardError
|
||||
#
|
||||
end
|
||||
end
|
||||
|
||||
if wizard_ids.empty?
|
||||
return render_error(I18n.t('wizard.export.error.invalid_wizards'))
|
||||
end
|
||||
return render_error(I18n.t("wizard.export.error.invalid_wizards")) if wizard_ids.empty?
|
||||
|
||||
@wizard_ids = wizard_ids
|
||||
end
|
||||
|
|
|
@ -4,27 +4,30 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
|
|||
before_action :find_wizard, except: [:index]
|
||||
|
||||
def index
|
||||
render json: ActiveModel::ArraySerializer.new(
|
||||
render json:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
CustomWizard::Wizard.list(current_user),
|
||||
each_serializer: CustomWizard::BasicWizardSerializer
|
||||
each_serializer: CustomWizard::BasicWizardSerializer,
|
||||
)
|
||||
end
|
||||
|
||||
def show
|
||||
render_json_dump(
|
||||
wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false),
|
||||
submissions: ActiveModel::ArraySerializer.new(
|
||||
submissions:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
submission_list.submissions,
|
||||
each_serializer: CustomWizard::SubmissionSerializer
|
||||
each_serializer: CustomWizard::SubmissionSerializer,
|
||||
),
|
||||
total: submission_list.total
|
||||
total: submission_list.total,
|
||||
)
|
||||
end
|
||||
|
||||
def download
|
||||
content = ActiveModel::ArraySerializer.new(
|
||||
content =
|
||||
ActiveModel::ArraySerializer.new(
|
||||
CustomWizard::Submission.list(@wizard).submissions,
|
||||
each_serializer: CustomWizard::SubmissionSerializer
|
||||
each_serializer: CustomWizard::SubmissionSerializer,
|
||||
)
|
||||
|
||||
send_data content.to_json,
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
||||
before_action :find_wizard, only: [:show, :remove]
|
||||
before_action :find_wizard, only: %i[show remove]
|
||||
|
||||
def index
|
||||
render_json_dump(
|
||||
wizard_list: ActiveModel::ArraySerializer.new(
|
||||
wizard_list:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
CustomWizard::Wizard.list(current_user),
|
||||
each_serializer: CustomWizard::BasicWizardSerializer
|
||||
each_serializer: CustomWizard::BasicWizardSerializer,
|
||||
),
|
||||
field_types: CustomWizard::Field.types,
|
||||
realtime_validations: CustomWizard::RealtimeValidation.types,
|
||||
custom_fields: custom_field_list
|
||||
custom_fields: custom_field_list,
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -37,7 +38,10 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
|||
wizard_id = template.save(create: params[:create])
|
||||
|
||||
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
|
||||
render json: success_json.merge(wizard_id: wizard_id)
|
||||
end
|
||||
|
@ -52,16 +56,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
|||
:output,
|
||||
:output_type,
|
||||
:output_connector,
|
||||
pairs: [
|
||||
:index,
|
||||
:key,
|
||||
:key_type,
|
||||
:value,
|
||||
:value_type,
|
||||
:connector,
|
||||
value: [],
|
||||
key: [],
|
||||
],
|
||||
pairs: [:index, :key, :key_type, :value, :value_type, :connector, value: [], key: []],
|
||||
output: [],
|
||||
]
|
||||
end
|
||||
|
@ -120,9 +115,10 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
|||
content: mapped_params,
|
||||
condition: mapped_params,
|
||||
index: mapped_params,
|
||||
validations: {},
|
||||
validations: {
|
||||
},
|
||||
tag_groups: [],
|
||||
]
|
||||
],
|
||||
],
|
||||
actions: [
|
||||
:id,
|
||||
|
@ -169,8 +165,8 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
|||
visibility_level: mapped_params,
|
||||
members_visibility_level: mapped_params,
|
||||
add_event: mapped_params,
|
||||
add_location: mapped_params
|
||||
]
|
||||
add_location: mapped_params,
|
||||
],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,9 +8,7 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
|
|||
update[:fields] = {}
|
||||
if params[:fields]
|
||||
field_ids = @builder.wizard.field_ids
|
||||
params[:fields].each do |k, v|
|
||||
update[:fields][k] = v if field_ids.include? k
|
||||
end
|
||||
params[:fields].each { |k, v| update[:fields][k] = v if field_ids.include? k }
|
||||
end
|
||||
|
||||
@builder.build
|
||||
|
@ -34,16 +32,15 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
|
|||
|
||||
if current_step.final?
|
||||
builder.template.actions.each do |action_template|
|
||||
if action_template['run_after'] === 'wizard_completion'
|
||||
action_result = CustomWizard::Action.new(
|
||||
if action_template["run_after"] === "wizard_completion"
|
||||
action_result =
|
||||
CustomWizard::Action.new(
|
||||
action: action_template,
|
||||
wizard: @wizard,
|
||||
submission: current_submission
|
||||
submission: current_submission,
|
||||
).perform
|
||||
|
||||
if action_result.success?
|
||||
current_submission = action_result.submission
|
||||
end
|
||||
current_submission = action_result.submission if action_result.success?
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -68,14 +65,14 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
|
|||
result[:wizard] = ::CustomWizard::WizardSerializer.new(
|
||||
@wizard,
|
||||
scope: Guardian.new(current_user),
|
||||
root: false
|
||||
root: false,
|
||||
).as_json
|
||||
|
||||
render json: result
|
||||
else
|
||||
errors = []
|
||||
updater.errors.messages.each do |field, msg|
|
||||
errors << { field: field, description: msg.join(',') }
|
||||
errors << { field: field, description: msg.join(",") }
|
||||
end
|
||||
render json: { errors: errors }, status: 422
|
||||
end
|
||||
|
@ -87,15 +84,14 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
|
|||
raise Discourse::InvalidParameters.new(:wizard_id) if @builder.template.nil?
|
||||
raise Discourse::InvalidAccess.new if !@builder.wizard || !@builder.wizard.can_access?
|
||||
|
||||
@step_template = @builder.template.steps.select do |s|
|
||||
s['id'] == update_params[:step_id]
|
||||
end.first
|
||||
@step_template = @builder.template.steps.select { |s| s["id"] == update_params[:step_id] }.first
|
||||
raise Discourse::InvalidParameters.new(:step_id) if !@step_template
|
||||
raise Discourse::InvalidAccess.new if !@builder.check_condition(@step_template)
|
||||
end
|
||||
|
||||
def update_params
|
||||
@update_params || begin
|
||||
@update_params ||
|
||||
begin
|
||||
params.require(:step_id)
|
||||
params.require(:wizard_id)
|
||||
params.permit(:wizard_id, :step_id).transform_values { |v| v.underscore }
|
||||
|
@ -106,7 +102,7 @@ class CustomWizard::StepsController < ::CustomWizard::WizardClientController
|
|||
return @result[:redirect_on_next] if @result[:redirect_on_next].present?
|
||||
|
||||
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
|
||||
submission.route_to || submission.redirect_on_complete || submission.redirect_to
|
||||
end
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
class CustomWizard::WizardController < ::CustomWizard::WizardClientController
|
||||
def show
|
||||
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
|
||||
render json: { error: I18n.t('wizard.none') }
|
||||
render json: { error: I18n.t("wizard.none") }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -12,10 +13,10 @@ class CustomWizard::WizardController < ::CustomWizard::WizardClientController
|
|||
params.require(:wizard_id)
|
||||
|
||||
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
|
||||
|
||||
result = { success: 'OK' }
|
||||
result = { success: "OK" }
|
||||
|
||||
if current_user && wizard.can_access?
|
||||
if redirect_to = wizard.current_submission&.redirect_to
|
||||
|
@ -31,8 +32,9 @@ class CustomWizard::WizardController < ::CustomWizard::WizardClientController
|
|||
protected
|
||||
|
||||
def wizard
|
||||
@wizard ||= begin
|
||||
return nil unless @builder.present?
|
||||
@wizard ||=
|
||||
begin
|
||||
return nil if @builder.blank?
|
||||
@builder.build({ reset: params[:reset] }, params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,9 +6,7 @@ class CustomWizard::WizardClientController < ::ApplicationController
|
|||
private
|
||||
|
||||
def ensure_plugin_enabled
|
||||
unless SiteSetting.custom_wizard_enabled
|
||||
redirect_to path("/")
|
||||
end
|
||||
redirect_to path("/") unless SiteSetting.custom_wizard_enabled
|
||||
end
|
||||
|
||||
def guest_id
|
||||
|
|
|
@ -9,9 +9,7 @@ module Jobs
|
|||
user_ids = []
|
||||
|
||||
User.human_users.each do |user|
|
||||
if CustomWizard::Wizard.set_user_redirect(wizard.id, user)
|
||||
user_ids.push(user.id)
|
||||
end
|
||||
user_ids.push(user.id) if CustomWizard::Wizard.set_user_redirect(wizard.id, user)
|
||||
end
|
||||
|
||||
CustomWizard::Template.clear_cache_keys
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::Api::BasicEndpointSerializer < ::ApplicationSerializer
|
||||
attributes :id,
|
||||
:name
|
||||
attributes :id, :name
|
||||
end
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::Api::EndpointSerializer < ::ApplicationSerializer
|
||||
attributes :id,
|
||||
:name,
|
||||
:method,
|
||||
:url,
|
||||
:content_type,
|
||||
:success_codes
|
||||
attributes :id, :name, :method, :url, :content_type, :success_codes
|
||||
|
||||
def method
|
||||
object.send('method')
|
||||
object.send("method")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::ApiSerializer < ::ApplicationSerializer
|
||||
attributes :name,
|
||||
:title,
|
||||
:authorization,
|
||||
:endpoints,
|
||||
:log
|
||||
attributes :name, :title, :authorization, :endpoints, :log
|
||||
|
||||
def authorization
|
||||
if authorization = CustomWizard::Api::Authorization.get(object.name)
|
||||
CustomWizard::Api::AuthorizationSerializer.new(
|
||||
authorization,
|
||||
root: false
|
||||
)
|
||||
CustomWizard::Api::AuthorizationSerializer.new(authorization, root: false)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -19,17 +12,14 @@ class CustomWizard::ApiSerializer < ::ApplicationSerializer
|
|||
if endpoints = CustomWizard::Api::Endpoint.list(object.name)
|
||||
ActiveModel::ArraySerializer.new(
|
||||
endpoints,
|
||||
each_serializer: CustomWizard::Api::EndpointSerializer
|
||||
each_serializer: CustomWizard::Api::EndpointSerializer,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def log
|
||||
if log = CustomWizard::Api::LogEntry.list(object.name)
|
||||
ActiveModel::ArraySerializer.new(
|
||||
log,
|
||||
each_serializer: CustomWizard::Api::LogSerializer
|
||||
)
|
||||
ActiveModel::ArraySerializer.new(log, each_serializer: CustomWizard::Api::LogSerializer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::BasicApiSerializer < ::ApplicationSerializer
|
||||
attributes :name,
|
||||
:title,
|
||||
:endpoints
|
||||
attributes :name, :title, :endpoints
|
||||
|
||||
def endpoints
|
||||
if endpoints = CustomWizard::Api::Endpoint.list(object.name)
|
||||
ActiveModel::ArraySerializer.new(
|
||||
endpoints,
|
||||
each_serializer: CustomWizard::Api::BasicEndpointSerializer
|
||||
each_serializer: CustomWizard::Api::BasicEndpointSerializer,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CustomWizard::LogSerializer < ApplicationSerializer
|
||||
attributes :date,
|
||||
:action,
|
||||
:username,
|
||||
:message
|
||||
attributes :date, :action, :username, :message
|
||||
|
||||
has_one :user, serializer: ::BasicUserSerializer, embed: :objects
|
||||
end
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::SubmissionSerializer < ApplicationSerializer
|
||||
attributes :id,
|
||||
:fields,
|
||||
:submitted_at,
|
||||
:user
|
||||
attributes :id, :fields, :submitted_at, :user
|
||||
|
||||
def include_user?
|
||||
object.wizard.user.present?
|
||||
|
@ -14,17 +11,14 @@ class CustomWizard::SubmissionSerializer < ApplicationSerializer
|
|||
end
|
||||
|
||||
def fields
|
||||
@fields ||= begin
|
||||
@fields ||=
|
||||
begin
|
||||
result = {}
|
||||
|
||||
object.wizard.template['steps'].each do |step|
|
||||
step['fields'].each do |field|
|
||||
if value = object.fields[field['id']]
|
||||
result[field['id']] = {
|
||||
value: value,
|
||||
type: field['type'],
|
||||
label: field['label']
|
||||
}
|
||||
object.wizard.template["steps"].each do |step|
|
||||
step["fields"].each do |field|
|
||||
if value = object.fields[field["id"]]
|
||||
result[field["id"]] = { value: value, type: field["type"], label: field["label"] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||
|
||||
attributes :id,
|
||||
:index,
|
||||
:type,
|
||||
|
@ -109,7 +108,9 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
|||
object.validations&.each do |type, props|
|
||||
next unless props["status"]
|
||||
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
|
||||
|
||||
validations
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
|
||||
|
||||
attributes :start,
|
||||
:background,
|
||||
:submission_last_updated_at,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CustomWizard::StepSerializer < ::ApplicationSerializer
|
||||
|
||||
attributes :id,
|
||||
:index,
|
||||
:next,
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
CustomWizard::Engine.routes.draw do
|
||||
get ':wizard_id' => 'wizard#show'
|
||||
put ':wizard_id/skip' => 'wizard#skip'
|
||||
get ':wizard_id/steps' => 'wizard#show'
|
||||
get ':wizard_id/steps/:step_id' => 'wizard#show'
|
||||
put ':wizard_id/steps/:step_id' => 'steps#update'
|
||||
get ":wizard_id" => "wizard#show"
|
||||
put ":wizard_id/skip" => "wizard#skip"
|
||||
get ":wizard_id/steps" => "wizard#show"
|
||||
get ":wizard_id/steps/:step_id" => "wizard#show"
|
||||
put ":wizard_id/steps/:step_id" => "steps#update"
|
||||
end
|
||||
|
||||
Discourse::Application.routes.append do
|
||||
mount ::CustomWizard::Engine, at: 'w'
|
||||
post 'wizard/authorization/callback' => "custom_wizard/authorization#callback"
|
||||
get 'realtime-validations' => 'custom_wizard/realtime_validations#validate'
|
||||
mount ::CustomWizard::Engine, at: "w"
|
||||
post "wizard/authorization/callback" => "custom_wizard/authorization#callback"
|
||||
get "realtime-validations" => "custom_wizard/realtime_validations#validate"
|
||||
|
||||
scope module: 'custom_wizard', constraints: AdminConstraint.new do
|
||||
get 'admin/wizards' => 'admin#index'
|
||||
get 'admin/wizards/subscription' => 'subscription#index'
|
||||
scope module: "custom_wizard", constraints: AdminConstraint.new do
|
||||
get "admin/wizards" => "admin#index"
|
||||
get "admin/wizards/subscription" => "subscription#index"
|
||||
|
||||
get 'admin/wizards/wizard' => 'admin_wizard#index'
|
||||
get 'admin/wizards/wizard/create' => 'admin#index'
|
||||
get 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#show'
|
||||
put 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#save'
|
||||
delete 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#remove'
|
||||
get "admin/wizards/wizard" => "admin_wizard#index"
|
||||
get "admin/wizards/wizard/create" => "admin#index"
|
||||
get "admin/wizards/wizard/:wizard_id" => "admin_wizard#show"
|
||||
put "admin/wizards/wizard/:wizard_id" => "admin_wizard#save"
|
||||
delete "admin/wizards/wizard/:wizard_id" => "admin_wizard#remove"
|
||||
|
||||
get 'admin/wizards/custom-fields' => 'admin_custom_fields#index'
|
||||
put 'admin/wizards/custom-fields' => 'admin_custom_fields#update'
|
||||
delete 'admin/wizards/custom-fields/:name' => 'admin_custom_fields#destroy'
|
||||
get "admin/wizards/custom-fields" => "admin_custom_fields#index"
|
||||
put "admin/wizards/custom-fields" => "admin_custom_fields#update"
|
||||
delete "admin/wizards/custom-fields/:name" => "admin_custom_fields#destroy"
|
||||
|
||||
get 'admin/wizards/submissions' => 'admin_submissions#index'
|
||||
get 'admin/wizards/submissions/:wizard_id' => 'admin_submissions#show'
|
||||
get 'admin/wizards/submissions/:wizard_id/download' => 'admin_submissions#download'
|
||||
get "admin/wizards/submissions" => "admin_submissions#index"
|
||||
get "admin/wizards/submissions/:wizard_id" => "admin_submissions#show"
|
||||
get "admin/wizards/submissions/:wizard_id/download" => "admin_submissions#download"
|
||||
|
||||
get 'admin/wizards/api' => 'admin_api#list'
|
||||
get 'admin/wizards/api/:name' => 'admin_api#find'
|
||||
put 'admin/wizards/api/:name' => 'admin_api#save'
|
||||
delete 'admin/wizards/api/:name' => 'admin_api#remove'
|
||||
delete 'admin/wizards/api/:name/logs' => 'admin_api#clearlogs'
|
||||
get 'admin/wizards/api/:name/redirect' => 'admin_api#redirect'
|
||||
get 'admin/wizards/api/:name/authorize' => 'admin_api#authorize'
|
||||
get "admin/wizards/api" => "admin_api#list"
|
||||
get "admin/wizards/api/:name" => "admin_api#find"
|
||||
put "admin/wizards/api/:name" => "admin_api#save"
|
||||
delete "admin/wizards/api/:name" => "admin_api#remove"
|
||||
delete "admin/wizards/api/:name/logs" => "admin_api#clearlogs"
|
||||
get "admin/wizards/api/:name/redirect" => "admin_api#redirect"
|
||||
get "admin/wizards/api/:name/authorize" => "admin_api#authorize"
|
||||
|
||||
get 'admin/wizards/logs' => 'admin_logs#index'
|
||||
get 'admin/wizards/logs/:wizard_id' => 'admin_logs#show'
|
||||
get "admin/wizards/logs" => "admin_logs#index"
|
||||
get "admin/wizards/logs/:wizard_id" => "admin_logs#show"
|
||||
|
||||
get 'admin/wizards/manager' => 'admin_manager#index'
|
||||
get 'admin/wizards/manager/export' => 'admin_manager#export'
|
||||
post 'admin/wizards/manager/import' => 'admin_manager#import'
|
||||
delete 'admin/wizards/manager/destroy' => 'admin_manager#destroy'
|
||||
get "admin/wizards/manager" => "admin_manager#index"
|
||||
get "admin/wizards/manager/export" => "admin_manager#export"
|
||||
post "admin/wizards/manager/import" => "admin_manager#import"
|
||||
delete "admin/wizards/manager/destroy" => "admin_manager#destroy"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
watch_category_wizards = PluginStoreRow.where("
|
||||
watch_category_wizards =
|
||||
PluginStoreRow.where(
|
||||
"
|
||||
plugin_name = 'custom_wizard' AND
|
||||
value::jsonb -> 'actions' @> '[{ \"type\" : \"watch_categories\" }]'::jsonb
|
||||
")
|
||||
",
|
||||
)
|
||||
|
||||
if watch_category_wizards.exists?
|
||||
watch_category_wizards.each do |row|
|
||||
|
@ -14,10 +17,8 @@ class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0]
|
|||
next
|
||||
end
|
||||
|
||||
wizard_json['actions'].each do |a|
|
||||
if a['type'] === "watch_categories" && a['wizard_user'] == nil
|
||||
a['wizard_user'] = true
|
||||
end
|
||||
wizard_json["actions"].each do |a|
|
||||
a["wizard_user"] = true if a["type"] === "watch_categories" && a["wizard_user"] == nil
|
||||
end
|
||||
|
||||
row.value = wizard_json.to_json
|
||||
|
|
|
@ -5,7 +5,7 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
|
|||
action: "action",
|
||||
user: "username",
|
||||
date: "date",
|
||||
message: "message"
|
||||
message: "message",
|
||||
}
|
||||
|
||||
def change
|
||||
|
@ -23,22 +23,21 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
|
|||
next
|
||||
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 = []
|
||||
|
||||
# assumes no whitespace in the values
|
||||
attr_strs << log_json['message'].slice!(/(wizard: \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!(/(wizard: \S*; )/, 1)
|
||||
attr_strs << log_json["message"].slice!(/(action: \S*; )/, 1)
|
||||
attr_strs << log_json["message"].slice!(/(user: \S*; )/, 1)
|
||||
|
||||
attr_strs.each do |attr_str|
|
||||
if attr_str.is_a? String
|
||||
attr_str.gsub!(/[;]/ , "")
|
||||
key, value = attr_str.split(': ')
|
||||
attr_str.gsub!(/[;]/, "")
|
||||
key, value = attr_str.split(": ")
|
||||
value.strip! if value
|
||||
key = KEY_MAP[key.to_sym] ? KEY_MAP[key.to_sym] : key
|
||||
log_json[key] = value ? value : ''
|
||||
log_json[key] = value ? value : ""
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -61,22 +60,25 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
|
|||
end
|
||||
|
||||
# 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 = ""
|
||||
|
||||
if prefixes.present?
|
||||
message_prefix = prefixes.map do |k, v|
|
||||
message_prefix =
|
||||
prefixes
|
||||
.map do |k, v|
|
||||
key = KEY_MAP.key(k) ? KEY_MAP.key(k) : k
|
||||
"#{key.to_s}: #{v};"
|
||||
end.join(' ')
|
||||
"#{key}: #{v};"
|
||||
end
|
||||
.join(" ")
|
||||
end
|
||||
|
||||
if log_json.key?('message')
|
||||
message = log_json['message']
|
||||
if log_json.key?("message")
|
||||
message = log_json["message"]
|
||||
message = "#{message_prefix} #{message}" if message_prefix.present?
|
||||
log_json['message'] = message
|
||||
log_json["message"] = message
|
||||
else
|
||||
log_json['message'] = message_prefix
|
||||
log_json["message"] = message_prefix
|
||||
end
|
||||
|
||||
row.value = log_json.to_json
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::Action
|
||||
attr_accessor :submission,
|
||||
:action,
|
||||
:user,
|
||||
:guardian,
|
||||
:result
|
||||
attr_accessor :submission, :action, :user, :guardian, :result
|
||||
|
||||
REQUIRES_USER = %w[
|
||||
update_profile
|
||||
open_composer
|
||||
watch_categories
|
||||
add_to_group
|
||||
]
|
||||
REQUIRES_USER = %w[update_profile open_composer watch_categories add_to_group]
|
||||
|
||||
WIZARD_USER = 'wizard-user'
|
||||
WIZARD_USER = "wizard-user"
|
||||
|
||||
def initialize(opts)
|
||||
@wizard = opts[:wizard]
|
||||
|
@ -26,23 +17,17 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def perform
|
||||
if REQUIRES_USER.include?(action['id']) && !@user
|
||||
log_error("action requires user", "id: #{action['id']};")
|
||||
if REQUIRES_USER.include?(action["id"]) && !@user
|
||||
log_error("action requires user", "id: #{action["id"]};")
|
||||
@result.success = false
|
||||
return @result
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
self.send(action['type'].to_sym)
|
||||
end
|
||||
ActiveRecord::Base.transaction { self.send(action["type"].to_sym) }
|
||||
|
||||
if creates_post? && @result.success?
|
||||
@result.handler.enqueue_jobs
|
||||
end
|
||||
@result.handler.enqueue_jobs if creates_post? && @result.success?
|
||||
|
||||
if @result.success? && @result.output.present?
|
||||
@submission.fields[action['id']] = @result.output
|
||||
end
|
||||
@submission.fields[action["id"]] = @result.output if @result.success? && @result.output.present?
|
||||
|
||||
save_log
|
||||
|
||||
|
@ -76,7 +61,7 @@ class CustomWizard::Action
|
|||
if creator.errors.present?
|
||||
messages = creator.errors.full_messages.join(" ")
|
||||
log_error("failed to create", messages)
|
||||
elsif action['skip_redirect'].blank?
|
||||
elsif action["skip_redirect"].blank?
|
||||
@submission.redirect_on_complete = post.topic.url
|
||||
end
|
||||
|
||||
|
@ -91,12 +76,9 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def send_message
|
||||
if action['required'].present?
|
||||
required = CustomWizard::Mapper.new(
|
||||
inputs: action['required'],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
if action["required"].present?
|
||||
required =
|
||||
CustomWizard::Mapper.new(inputs: action["required"], data: mapper_data, user: user).perform
|
||||
|
||||
if required.blank?
|
||||
log_error("required input not present")
|
||||
|
@ -106,11 +88,12 @@ class CustomWizard::Action
|
|||
|
||||
params = basic_topic_params
|
||||
|
||||
targets = CustomWizard::Mapper.new(
|
||||
inputs: action['recipient'],
|
||||
targets =
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: action["recipient"],
|
||||
data: mapper_data,
|
||||
user: user,
|
||||
multiple: true
|
||||
multiple: true,
|
||||
).perform
|
||||
|
||||
if targets.blank?
|
||||
|
@ -131,12 +114,11 @@ class CustomWizard::Action
|
|||
end
|
||||
end
|
||||
|
||||
if params[:title].present? &&
|
||||
params[:raw].present? &&
|
||||
(params[:target_usernames].present? ||
|
||||
params[:target_group_names].present? ||
|
||||
params[:target_emails].present?)
|
||||
|
||||
if params[:title].present? && params[:raw].present? &&
|
||||
(
|
||||
params[:target_usernames].present? || params[:target_group_names].present? ||
|
||||
params[:target_emails].present?
|
||||
)
|
||||
params[:archetype] = Archetype.private_message
|
||||
|
||||
creator = PostCreator.new(topic_poster, params)
|
||||
|
@ -145,7 +127,7 @@ class CustomWizard::Action
|
|||
if creator.errors.present?
|
||||
messages = creator.errors.full_messages.join(" ")
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -157,7 +139,7 @@ class CustomWizard::Action
|
|||
else
|
||||
log_error(
|
||||
"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
|
||||
|
@ -165,19 +147,14 @@ class CustomWizard::Action
|
|||
def update_profile
|
||||
params = {}
|
||||
|
||||
if (profile_updates = action['profile_updates'])
|
||||
if (profile_updates = action["profile_updates"])
|
||||
profile_updates.first[:pairs].each do |pair|
|
||||
if allowed_profile_field?(pair['key'])
|
||||
key = cast_profile_key(pair['key'])
|
||||
value = cast_profile_value(
|
||||
mapper.map_field(
|
||||
pair['value'],
|
||||
pair['value_type']
|
||||
),
|
||||
pair['key']
|
||||
)
|
||||
if allowed_profile_field?(pair["key"])
|
||||
key = cast_profile_key(pair["key"])
|
||||
value =
|
||||
cast_profile_value(mapper.map_field(pair["value"], pair["value_type"]), pair["key"])
|
||||
|
||||
if user_field?(pair['key'])
|
||||
if user_field?(pair["key"])
|
||||
params[:custom_fields] ||= {}
|
||||
params[:custom_fields][key] = value
|
||||
else
|
||||
|
@ -192,12 +169,10 @@ class CustomWizard::Action
|
|||
if params.present?
|
||||
result = UserUpdater.new(Discourse.system_user, user).update(params)
|
||||
|
||||
if params[:avatar].present?
|
||||
result = update_avatar(params[:avatar])
|
||||
end
|
||||
result = update_avatar(params[:avatar]) if params[:avatar].present?
|
||||
|
||||
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
|
||||
log_error("failed to update profile fields", "result: #{result.inspect}")
|
||||
end
|
||||
|
@ -207,14 +182,10 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def watch_tags
|
||||
tags = CustomWizard::Mapper.new(
|
||||
inputs: action['tags'],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
tags = CustomWizard::Mapper.new(inputs: action["tags"], data: mapper_data, user: user).perform
|
||||
|
||||
tags = [*tags]
|
||||
level = action['notification_level'].to_sym
|
||||
level = action["notification_level"].to_sym
|
||||
|
||||
if level.blank?
|
||||
log_error("Notifcation Level was not set. Exiting watch tags action")
|
||||
|
@ -223,23 +194,17 @@ class CustomWizard::Action
|
|||
|
||||
users = []
|
||||
|
||||
if action['usernames']
|
||||
mapped_users = CustomWizard::Mapper.new(
|
||||
inputs: action['usernames'],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
if action["usernames"]
|
||||
mapped_users =
|
||||
CustomWizard::Mapper.new(inputs: action["usernames"], data: mapper_data, user: user).perform
|
||||
|
||||
if mapped_users.present?
|
||||
mapped_users = mapped_users.split(',')
|
||||
.map { |username| User.find_by(username: username) }
|
||||
mapped_users = mapped_users.split(",").map { |username| User.find_by(username: username) }
|
||||
users.push(*mapped_users)
|
||||
end
|
||||
end
|
||||
|
||||
if ActiveRecord::Type::Boolean.new.cast(action['wizard_user'])
|
||||
users.push(user)
|
||||
end
|
||||
users.push(user) if ActiveRecord::Type::Boolean.new.cast(action["wizard_user"])
|
||||
|
||||
users.each do |user|
|
||||
result = TagUser.batch_set(user, level, tags)
|
||||
|
@ -253,46 +218,38 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def watch_categories
|
||||
watched_categories = CustomWizard::Mapper.new(
|
||||
inputs: action['categories'],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
watched_categories =
|
||||
CustomWizard::Mapper.new(inputs: action["categories"], data: mapper_data, user: user).perform
|
||||
|
||||
watched_categories = [*watched_categories].map(&:to_i)
|
||||
|
||||
notification_level = action['notification_level']
|
||||
notification_level = action["notification_level"]
|
||||
|
||||
if notification_level.blank?
|
||||
log_error("Notifcation Level was not set. Exiting wizard action")
|
||||
return
|
||||
end
|
||||
|
||||
mute_remainder = CustomWizard::Mapper.new(
|
||||
inputs: action['mute_remainder'],
|
||||
mute_remainder =
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: action["mute_remainder"],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
user: user,
|
||||
).perform
|
||||
|
||||
users = []
|
||||
|
||||
if action['usernames']
|
||||
mapped_users = CustomWizard::Mapper.new(
|
||||
inputs: action['usernames'],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
if action["usernames"]
|
||||
mapped_users =
|
||||
CustomWizard::Mapper.new(inputs: action["usernames"], data: mapper_data, user: user).perform
|
||||
|
||||
if mapped_users.present?
|
||||
mapped_users = mapped_users.split(',')
|
||||
.map { |username| User.find_by(username: username) }
|
||||
mapped_users = mapped_users.split(",").map { |username| User.find_by(username: username) }
|
||||
users.push(*mapped_users)
|
||||
end
|
||||
end
|
||||
|
||||
if ActiveRecord::Type::Boolean.new.cast(action['wizard_user'])
|
||||
users.push(user)
|
||||
end
|
||||
users.push(user) if ActiveRecord::Type::Boolean.new.cast(action["wizard_user"])
|
||||
|
||||
category_ids = Category.all.pluck(:id)
|
||||
set_level = CategoryUser.notification_levels[notification_level.to_sym]
|
||||
|
@ -308,37 +265,35 @@ class CustomWizard::Action
|
|||
new_level = mute_level
|
||||
end
|
||||
|
||||
if new_level
|
||||
CategoryUser.set_notification_level_for_category(user, new_level, category_id)
|
||||
end
|
||||
CategoryUser.set_notification_level_for_category(user, new_level, category_id) if new_level
|
||||
end
|
||||
|
||||
if watched_categories.any?
|
||||
log_success("#{user.username} notifications for #{watched_categories} set to #{set_level}")
|
||||
end
|
||||
|
||||
if mute_remainder
|
||||
log_success("#{user.username} notifications for all other categories muted")
|
||||
end
|
||||
log_success("#{user.username} notifications for all other categories muted") if mute_remainder
|
||||
end
|
||||
end
|
||||
|
||||
def send_to_api
|
||||
api_body = nil
|
||||
|
||||
if action['api_body'] != ""
|
||||
if action["api_body"] != ""
|
||||
begin
|
||||
api_body_parsed = JSON.parse(action['api_body'])
|
||||
api_body_parsed = JSON.parse(action["api_body"])
|
||||
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
|
||||
api_body = JSON.parse(mapper.interpolate(JSON.generate(api_body_parsed)))
|
||||
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'])
|
||||
error = error['message'] || error
|
||||
if error = result["error"] || (result[0] && result[0]["error"])
|
||||
error = error["message"] || error
|
||||
log_error("api request failed", "message: #{error}")
|
||||
else
|
||||
log_success("api request succeeded", "result: #{result}")
|
||||
|
@ -357,7 +312,7 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
if tags = action_tags
|
||||
url += "&tags=#{tags.join(',')}"
|
||||
url += "&tags=#{tags.join(",")}"
|
||||
end
|
||||
|
||||
route_to = Discourse.base_uri + url
|
||||
|
@ -370,13 +325,14 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def add_to_group
|
||||
group_map = CustomWizard::Mapper.new(
|
||||
inputs: action['group'],
|
||||
group_map =
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: action["group"],
|
||||
data: mapper_data,
|
||||
user: user,
|
||||
opts: {
|
||||
multiple: true
|
||||
}
|
||||
multiple: true,
|
||||
},
|
||||
).perform
|
||||
|
||||
group_map = group_map.flatten.compact
|
||||
|
@ -386,7 +342,8 @@ class CustomWizard::Action
|
|||
return
|
||||
end
|
||||
|
||||
groups = group_map.reduce([]) do |result, g|
|
||||
groups =
|
||||
group_map.reduce([]) do |result, g|
|
||||
begin
|
||||
result.push(Integer(g))
|
||||
rescue ArgumentError
|
||||
|
@ -407,29 +364,25 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
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
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
def route_to
|
||||
return if (url_input = action['url']).blank?
|
||||
return if (url_input = action["url"]).blank?
|
||||
|
||||
if url_input.is_a?(String)
|
||||
url = mapper.interpolate(url_input)
|
||||
else
|
||||
url = CustomWizard::Mapper.new(
|
||||
inputs: url_input,
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
url = CustomWizard::Mapper.new(inputs: url_input, data: mapper_data, user: user).perform
|
||||
end
|
||||
|
||||
if action['code'].present?
|
||||
@submission.fields[action['code']] = SecureRandom.hex(8)
|
||||
url += "&#{action['code']}=#{@submission.fields[action['code']]}"
|
||||
if action["code"].present?
|
||||
@submission.fields[action["code"]] = SecureRandom.hex(8)
|
||||
url += "&#{action["code"]}=#{@submission.fields[action["code"]]}"
|
||||
end
|
||||
|
||||
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) }
|
||||
end
|
||||
|
||||
if group.save
|
||||
log_success("Group created", group.name)
|
||||
end
|
||||
log_success("Group created", group.name) if group.save
|
||||
|
||||
result.output = group.name
|
||||
else
|
||||
|
@ -504,11 +455,8 @@ class CustomWizard::Action
|
|||
private
|
||||
|
||||
def action_category
|
||||
output = CustomWizard::Mapper.new(
|
||||
inputs: action['category'],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
output =
|
||||
CustomWizard::Mapper.new(inputs: action["category"], data: mapper_data, user: user).perform
|
||||
|
||||
return false if output.blank?
|
||||
|
||||
|
@ -522,32 +470,26 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def action_tags
|
||||
output = CustomWizard::Mapper.new(
|
||||
inputs: action['tags'],
|
||||
data: mapper_data,
|
||||
user: user,
|
||||
).perform
|
||||
output = CustomWizard::Mapper.new(inputs: action["tags"], data: mapper_data, user: user).perform
|
||||
|
||||
return false if output.blank?
|
||||
|
||||
if output.is_a?(Array)
|
||||
output.flatten
|
||||
else output.is_a?(String)
|
||||
else
|
||||
output.is_a?(String)
|
||||
[*output]
|
||||
end
|
||||
end
|
||||
|
||||
def add_custom_fields(params = {})
|
||||
if (custom_fields = action['custom_fields']).present?
|
||||
field_map = CustomWizard::Mapper.new(
|
||||
inputs: custom_fields,
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
if (custom_fields = action["custom_fields"]).present?
|
||||
field_map =
|
||||
CustomWizard::Mapper.new(inputs: custom_fields, data: mapper_data, user: user).perform
|
||||
registered_fields = CustomWizard::CustomField.full_list
|
||||
|
||||
field_map.each do |field|
|
||||
keyArr = field[:key].split('.')
|
||||
keyArr = field[:key].split(".")
|
||||
value = field[:value]
|
||||
|
||||
if keyArr.length > 1
|
||||
|
@ -601,28 +543,32 @@ class CustomWizard::Action
|
|||
skip_validations: true,
|
||||
topic_opts: {
|
||||
custom_fields: {
|
||||
wizard_submission_id: @wizard.current_submission.id
|
||||
}
|
||||
}
|
||||
wizard_submission_id: @wizard.current_submission.id,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
params[:title] = CustomWizard::Mapper.new(
|
||||
inputs: action['title'],
|
||||
inputs: action["title"],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
user: user,
|
||||
).perform
|
||||
|
||||
params[:raw] = action['post_builder'] ?
|
||||
params[:raw] = (
|
||||
if action["post_builder"]
|
||||
mapper.interpolate(
|
||||
action['post_template'],
|
||||
action["post_template"],
|
||||
user: true,
|
||||
value: true,
|
||||
wizard: true,
|
||||
template: true
|
||||
) :
|
||||
@submission.fields[action['post']]
|
||||
template: true,
|
||||
)
|
||||
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)
|
||||
end
|
||||
|
@ -644,7 +590,7 @@ class CustomWizard::Action
|
|||
params[field.to_sym] = CustomWizard::Mapper.new(
|
||||
inputs: action[field],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
user: user,
|
||||
).perform
|
||||
end
|
||||
end
|
||||
|
@ -654,12 +600,10 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def topic_poster
|
||||
@topic_poster ||= begin
|
||||
poster_id = CustomWizard::Mapper.new(
|
||||
inputs: action['poster'],
|
||||
data: mapper_data,
|
||||
user: user,
|
||||
).perform
|
||||
@topic_poster ||=
|
||||
begin
|
||||
poster_id =
|
||||
CustomWizard::Mapper.new(inputs: action["poster"], data: mapper_data, user: user).perform
|
||||
poster_id = [*poster_id].first if poster_id.present?
|
||||
|
||||
if poster_id.blank? || poster_id === WIZARD_USER
|
||||
|
@ -673,13 +617,11 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def guest_user
|
||||
@guest_user ||= begin
|
||||
return nil unless action['guest_email']
|
||||
@guest_user ||=
|
||||
begin
|
||||
return nil unless action["guest_email"]
|
||||
|
||||
email = CustomWizard::Mapper.new(
|
||||
inputs: action['guest_email'],
|
||||
data: mapper_data,
|
||||
).perform
|
||||
email = CustomWizard::Mapper.new(inputs: action["guest_email"], data: mapper_data).perform
|
||||
|
||||
if email&.match(/@/)
|
||||
if user = User.find_by_email(email)
|
||||
|
@ -699,7 +641,7 @@ class CustomWizard::Action
|
|||
def new_group_params
|
||||
params = {}
|
||||
|
||||
%w(
|
||||
%w[
|
||||
name
|
||||
full_name
|
||||
title
|
||||
|
@ -711,26 +653,18 @@ class CustomWizard::Action
|
|||
visibility_level
|
||||
members_visibility_level
|
||||
grant_trust_level
|
||||
).each do |attr|
|
||||
].each do |attr|
|
||||
input = action[attr]
|
||||
|
||||
if attr === "name" && input.blank?
|
||||
raise ArgumentError.new
|
||||
end
|
||||
raise ArgumentError.new if attr === "name" && input.blank?
|
||||
|
||||
if attr === "full_name" && input.blank?
|
||||
input = action["name"]
|
||||
end
|
||||
input = action["name"] if attr === "full_name" && input.blank?
|
||||
|
||||
if input.present?
|
||||
value = CustomWizard::Mapper.new(
|
||||
inputs: input,
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
value = CustomWizard::Mapper.new(inputs: input, data: mapper_data, user: user).perform
|
||||
|
||||
if value
|
||||
value = value.parameterize(separator: '_') if attr === "name"
|
||||
value = value.parameterize(separator: "_") if attr === "name"
|
||||
value = value.to_i if attr.include?("_level")
|
||||
|
||||
params[attr.to_sym] = value
|
||||
|
@ -744,25 +678,13 @@ class CustomWizard::Action
|
|||
def new_category_params
|
||||
params = {}
|
||||
|
||||
%w(
|
||||
name
|
||||
slug
|
||||
color
|
||||
text_color
|
||||
parent_category_id
|
||||
permissions
|
||||
).each do |attr|
|
||||
%w[name slug color text_color parent_category_id permissions].each do |attr|
|
||||
if action[attr].present?
|
||||
value = CustomWizard::Mapper.new(
|
||||
inputs: action[attr],
|
||||
data: mapper_data,
|
||||
user: user
|
||||
).perform
|
||||
value =
|
||||
CustomWizard::Mapper.new(inputs: action[attr], data: mapper_data, user: user).perform
|
||||
|
||||
if value
|
||||
if attr === "parent_category_id" && value.is_a?(Array)
|
||||
value = value[0]
|
||||
end
|
||||
value = value[0] if attr === "parent_category_id" && value.is_a?(Array)
|
||||
|
||||
if attr === "permissions" && value.is_a?(Array)
|
||||
permissions = value
|
||||
|
@ -776,16 +698,14 @@ class CustomWizard::Action
|
|||
group = Group.find_by(id: k[0])
|
||||
k = group.name
|
||||
else
|
||||
k = k.parameterize(separator: '_')
|
||||
k = k.parameterize(separator: "_")
|
||||
end
|
||||
|
||||
value[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
if attr === 'slug'
|
||||
value = value.parameterize(separator: '-')
|
||||
end
|
||||
value = value.parameterize(separator: "-") if attr === "slug"
|
||||
|
||||
params[attr.to_sym] = value
|
||||
end
|
||||
|
@ -796,15 +716,15 @@ class CustomWizard::Action
|
|||
end
|
||||
|
||||
def creates_post?
|
||||
[:create_topic, :send_message].include?(action['type'].to_sym)
|
||||
%i[create_topic send_message].include?(action["type"].to_sym)
|
||||
end
|
||||
|
||||
def public_topic_fields
|
||||
['visible']
|
||||
["visible"]
|
||||
end
|
||||
|
||||
def profile_url_fields
|
||||
['profile_background', 'card_background']
|
||||
%w[profile_background card_background]
|
||||
end
|
||||
|
||||
def cast_profile_key(key)
|
||||
|
@ -819,16 +739,16 @@ class CustomWizard::Action
|
|||
return value if value.nil?
|
||||
|
||||
if profile_url_fields.include?(key)
|
||||
value['url']
|
||||
elsif key === 'avatar'
|
||||
value['id']
|
||||
value["url"]
|
||||
elsif key === "avatar"
|
||||
value["id"]
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def profile_excluded_fields
|
||||
['username', 'email', 'trust_level'].freeze
|
||||
%w[username email trust_level].freeze
|
||||
end
|
||||
|
||||
def allowed_profile_field?(field)
|
||||
|
@ -837,13 +757,12 @@ class CustomWizard::Action
|
|||
|
||||
def user_field?(field)
|
||||
field.to_s.include?(::User::USER_FIELD_PREFIX) &&
|
||||
::UserField.exists?(field.split('_').last.to_i)
|
||||
::UserField.exists?(field.split("_").last.to_i)
|
||||
end
|
||||
|
||||
def allowed_profile_fields
|
||||
CustomWizard::Mapper.user_fields.select { |f| profile_excluded_fields.exclude?(f) } +
|
||||
profile_url_fields +
|
||||
['avatar']
|
||||
profile_url_fields + ["avatar"]
|
||||
end
|
||||
|
||||
def update_avatar(upload_id)
|
||||
|
@ -875,11 +794,6 @@ class CustomWizard::Action
|
|||
def save_log
|
||||
username = user ? user.username : @wizard.actor_id
|
||||
|
||||
CustomWizard::Log.create(
|
||||
@wizard.id,
|
||||
action['type'],
|
||||
username,
|
||||
@log.join('; ')
|
||||
)
|
||||
CustomWizard::Log.create(@wizard.id, action["type"], username, @log.join("; "))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
class CustomWizard::Api
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
attr_accessor :name,
|
||||
:title
|
||||
attr_accessor :name, :title
|
||||
|
||||
def initialize(name, data = {})
|
||||
@name = name
|
||||
data.each do |k, v|
|
||||
self.send "#{k}=", v if self.respond_to?(k)
|
||||
end
|
||||
data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
|
||||
end
|
||||
|
||||
def self.set(name, data)
|
||||
|
@ -27,9 +24,10 @@ class CustomWizard::Api
|
|||
end
|
||||
|
||||
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|
|
||||
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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
require 'excon'
|
||||
require "excon"
|
||||
|
||||
class CustomWizard::Api::Authorization
|
||||
include ActiveModel::SerializerSupport
|
||||
|
@ -23,9 +23,7 @@ class CustomWizard::Api::Authorization
|
|||
def initialize(api_name, data = {})
|
||||
@api_name = api_name
|
||||
|
||||
data.each do |k, v|
|
||||
self.send "#{k}=", v if self.respond_to?(k)
|
||||
end
|
||||
data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
|
||||
end
|
||||
|
||||
def authorized
|
||||
|
@ -33,16 +31,13 @@ class CustomWizard::Api::Authorization
|
|||
end
|
||||
|
||||
def self.set(api_name, new_data = {})
|
||||
|
||||
api_name = api_name.underscore
|
||||
|
||||
data = self.get(api_name, data_only: true) || {}
|
||||
|
||||
new_data.each do |k, v|
|
||||
data[k.to_sym] = v
|
||||
end
|
||||
new_data.each { |k, v| data[k.to_sym] = v }
|
||||
|
||||
PluginStore.set("custom_wizard_api_#{api_name}", 'authorization', data)
|
||||
PluginStore.set("custom_wizard_api_#{api_name}", "authorization", data)
|
||||
|
||||
self.get(api_name)
|
||||
end
|
||||
|
@ -50,7 +45,7 @@ class CustomWizard::Api::Authorization
|
|||
def self.get(api_name, opts = {})
|
||||
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]
|
||||
data
|
||||
else
|
||||
|
@ -67,14 +62,14 @@ class CustomWizard::Api::Authorization
|
|||
|
||||
def self.authorization_string(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"
|
||||
raise Discourse::InvalidParameters.new(:username) unless auth.username.present?
|
||||
raise Discourse::InvalidParameters.new(:password) unless auth.password.present?
|
||||
raise Discourse::InvalidParameters.new(:username) if auth.username.blank?
|
||||
raise Discourse::InvalidParameters.new(:password) if auth.password.blank?
|
||||
"Basic #{Base64.strict_encode64((auth.username + ":" + auth.password).chomp)}"
|
||||
elsif ['oauth_3', 'oauth_2'].include?(auth.auth_type)
|
||||
raise Discourse::InvalidParameters.new(auth.access_token) unless auth.access_token.present?
|
||||
elsif %w[oauth_3 oauth_2].include?(auth.auth_type)
|
||||
raise Discourse::InvalidParameters.new(auth.access_token) if auth.access_token.blank?
|
||||
"Bearer #{auth.access_token}"
|
||||
else
|
||||
nil
|
||||
|
@ -87,38 +82,51 @@ class CustomWizard::Api::Authorization
|
|||
|
||||
body = {}
|
||||
|
||||
if opts[:refresh] && type === 'oauth_3'
|
||||
body['grant_type'] = 'refresh_token'
|
||||
elsif type === 'oauth_2'
|
||||
body['grant_type'] = 'client_credentials'
|
||||
elsif type === 'oauth_3'
|
||||
body['grant_type'] = 'authorization_code'
|
||||
if opts[:refresh] && type === "oauth_3"
|
||||
body["grant_type"] = "refresh_token"
|
||||
elsif type === "oauth_2"
|
||||
body["grant_type"] = "client_credentials"
|
||||
elsif type === "oauth_3"
|
||||
body["grant_type"] = "authorization_code"
|
||||
end
|
||||
|
||||
unless opts[:refresh]
|
||||
body['client_id'] = authorization.client_id
|
||||
body['client_secret'] = authorization.client_secret
|
||||
body["client_id"] = authorization.client_id
|
||||
body["client_secret"] = authorization.client_secret
|
||||
end
|
||||
|
||||
if type === 'oauth_3'
|
||||
body['code'] = authorization.code
|
||||
body['redirect_uri'] = Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
|
||||
if type === "oauth_3"
|
||||
body["code"] = authorization.code
|
||||
body["redirect_uri"] = Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
|
||||
end
|
||||
|
||||
connection = Excon.new(
|
||||
connection =
|
||||
Excon.new(
|
||||
authorization.token_url,
|
||||
headers: {
|
||||
"Content-Type" => "application/x-www-form-urlencoded"
|
||||
"Content-Type" => "application/x-www-form-urlencoded",
|
||||
},
|
||||
method: 'GET',
|
||||
query: URI.encode_www_form(body)
|
||||
method: "GET",
|
||||
query: URI.encode_www_form(body),
|
||||
)
|
||||
begin
|
||||
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)
|
||||
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)
|
||||
end
|
||||
|
||||
|
@ -128,25 +136,21 @@ class CustomWizard::Api::Authorization
|
|||
def self.handle_token_result(name, result)
|
||||
result_data = JSON.parse(result.body)
|
||||
|
||||
if result_data['error']
|
||||
return result_data
|
||||
end
|
||||
return result_data if result_data["error"]
|
||||
|
||||
data = {}
|
||||
|
||||
data['access_token'] = result_data['access_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["access_token"] = result_data["access_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"]
|
||||
|
||||
if result_data['expires_in']
|
||||
data['token_expires_at'] = Time.now + result_data['expires_in'].seconds
|
||||
data['token_refresh_at'] = data['token_expires_at'].to_time - 10.minutes
|
||||
if result_data["expires_in"]
|
||||
data["token_expires_at"] = Time.now + result_data["expires_in"].seconds
|
||||
data["token_refresh_at"] = data["token_expires_at"].to_time - 10.minutes
|
||||
|
||||
opts = {
|
||||
name: name
|
||||
}
|
||||
opts = { 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
|
||||
|
||||
CustomWizard::Api::Authorization.set(name, data)
|
||||
|
|
|
@ -2,34 +2,24 @@
|
|||
class CustomWizard::Api::Endpoint
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
attr_accessor :id,
|
||||
:name,
|
||||
:api_name,
|
||||
:method,
|
||||
:url,
|
||||
:content_type,
|
||||
:success_codes
|
||||
attr_accessor :id, :name, :api_name, :method, :url, :content_type, :success_codes
|
||||
|
||||
def initialize(api_name, data = {})
|
||||
@api_name = api_name
|
||||
|
||||
data.each do |k, v|
|
||||
self.send "#{k}=", v if self.respond_to?(k)
|
||||
end
|
||||
data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
|
||||
end
|
||||
|
||||
def self.set(api_name, new_data)
|
||||
if new_data['id']
|
||||
data = self.get(api_name, new_data['id'], data_only: true)
|
||||
endpoint_id = new_data['id']
|
||||
if new_data["id"]
|
||||
data = self.get(api_name, new_data["id"], data_only: true)
|
||||
endpoint_id = new_data["id"]
|
||||
else
|
||||
data = {}
|
||||
endpoint_id = SecureRandom.hex(3)
|
||||
end
|
||||
|
||||
new_data.each do |k, v|
|
||||
data[k.to_sym] = v
|
||||
end
|
||||
new_data.each { |k, v| data[k.to_sym] = v }
|
||||
|
||||
PluginStore.set("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}", data)
|
||||
|
||||
|
@ -52,15 +42,18 @@ class CustomWizard::Api::Endpoint
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
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|
|
||||
api_name = record['plugin_name'].sub("custom_wizard_api_", "")
|
||||
data = ::JSON.parse(record['value'])
|
||||
data[:id] = record['key'].split('_').last
|
||||
api_name = record["plugin_name"].sub("custom_wizard_api_", "")
|
||||
data = ::JSON.parse(record["value"])
|
||||
data[:id] = record["key"].split("_").last
|
||||
self.new(api_name, data)
|
||||
end
|
||||
end
|
||||
|
@ -97,12 +90,12 @@ class CustomWizard::Api::Endpoint
|
|||
result = response.body
|
||||
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
|
||||
else
|
||||
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 }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,23 +16,19 @@ class CustomWizard::Api::LogEntry
|
|||
def initialize(api_name, data = {})
|
||||
@api_name = api_name
|
||||
|
||||
data.each do |k, v|
|
||||
self.send "#{k}=", v if self.respond_to?(k)
|
||||
end
|
||||
data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
|
||||
end
|
||||
|
||||
def self.set(api_name, new_data)
|
||||
if new_data['log_id']
|
||||
data = self.get(api_name, new_data['log_id'], data_only: true)
|
||||
log_id = new_data['log_id']
|
||||
if new_data["log_id"]
|
||||
data = self.get(api_name, new_data["log_id"], data_only: true)
|
||||
log_id = new_data["log_id"]
|
||||
else
|
||||
data = {}
|
||||
log_id = SecureRandom.hex(8)
|
||||
end
|
||||
|
||||
new_data.each do |k, v|
|
||||
data[k.to_sym] = v
|
||||
end
|
||||
new_data.each { |k, v| data[k.to_sym] = v }
|
||||
|
||||
PluginStore.set("custom_wizard_api_#{api_name}", "log_#{log_id}", data)
|
||||
|
||||
|
@ -55,16 +51,19 @@ class CustomWizard::Api::LogEntry
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
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|
|
||||
api_name = record['plugin_name'].sub("custom_wizard_api_", "")
|
||||
data = ::JSON.parse(record['value'])
|
||||
data[:log_id] = record['key'].split('_').last
|
||||
this_user = User.find_by(id: data['user_id'])
|
||||
api_name = record["plugin_name"].sub("custom_wizard_api_", "")
|
||||
data = ::JSON.parse(record["value"])
|
||||
data[:log_id] = record["key"].split("_").last
|
||||
this_user = User.find_by(id: data["user_id"])
|
||||
if this_user.nil?
|
||||
data[:user_id] = nil
|
||||
data[:username] = ""
|
||||
|
@ -76,14 +75,17 @@ class CustomWizard::Api::LogEntry
|
|||
data[:username] = this_user.username || ""
|
||||
data[:userpath] = "/u/#{this_user.username_lower}/activity"
|
||||
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
|
||||
self.new(api_name, data)
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -30,7 +30,7 @@ class CustomWizard::Builder
|
|||
@template.steps.each do |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)
|
||||
next if !step.permitted
|
||||
|
||||
|
@ -73,14 +73,15 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
def check_condition(template)
|
||||
if template['condition'].present?
|
||||
result = CustomWizard::Mapper.new(
|
||||
inputs: template['condition'],
|
||||
if template["condition"].present?
|
||||
result =
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: template["condition"],
|
||||
user: @wizard.user,
|
||||
data: @wizard.current_submission&.fields_and_meta,
|
||||
opts: {
|
||||
multiple: true
|
||||
}
|
||||
multiple: true,
|
||||
},
|
||||
).perform
|
||||
|
||||
result.any?
|
||||
|
@ -92,126 +93,121 @@ class CustomWizard::Builder
|
|||
private
|
||||
|
||||
def mapper
|
||||
CustomWizard::Mapper.new(
|
||||
user: @wizard.user,
|
||||
data: @wizard.current_submission&.fields_and_meta
|
||||
)
|
||||
CustomWizard::Mapper.new(user: @wizard.user, data: @wizard.current_submission&.fields_and_meta)
|
||||
end
|
||||
|
||||
def append_field(step, step_template, field_template, build_opts)
|
||||
params = {
|
||||
id: field_template['id'],
|
||||
type: field_template['type'],
|
||||
required: field_template['required']
|
||||
id: field_template["id"],
|
||||
type: field_template["type"],
|
||||
required: field_template["required"],
|
||||
}
|
||||
|
||||
%w(label description image key validations min_length max_length char_counter tag_groups).each do |key|
|
||||
params[key.to_sym] = field_template[key] if field_template[key]
|
||||
end
|
||||
%w[
|
||||
label
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
if field_template['type'] === 'group' && params[:value].present?
|
||||
if field_template["type"] === "group" && params[:value].present?
|
||||
params[:value] = params[:value].first
|
||||
end
|
||||
|
||||
if field_template['type'] === 'checkbox'
|
||||
params[:value] = standardise_boolean(params[:value])
|
||||
params[:value] = standardise_boolean(params[:value]) if field_template["type"] === "checkbox"
|
||||
|
||||
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
|
||||
|
||||
if field_template['type'] === 'upload'
|
||||
params[:file_types] = field_template['file_types']
|
||||
if %w[category tag topic].include?(field_template["type"])
|
||||
params[:limit] = field_template["limit"]
|
||||
end
|
||||
|
||||
if ['date', 'time', 'date_time'].include?(field_template['type'])
|
||||
params[:format] = field_template['format']
|
||||
if field_template["type"] === "tag"
|
||||
params[:can_create_tag] = standardise_boolean(field_template["can_create_tag"])
|
||||
end
|
||||
|
||||
if %w[category tag topic].include?(field_template['type'])
|
||||
params[:limit] = field_template['limit']
|
||||
end
|
||||
params[:property] = field_template["property"] if field_template["type"] === "category"
|
||||
|
||||
if field_template['type'] === 'tag'
|
||||
params[:can_create_tag] = standardise_boolean(field_template['can_create_tag'])
|
||||
end
|
||||
params[:category] = field_template["category"] if field_template["type"] === "topic"
|
||||
|
||||
if field_template['type'] === 'category'
|
||||
params[:property] = field_template['property']
|
||||
end
|
||||
|
||||
if field_template['type'] === 'topic'
|
||||
params[:category] = field_template['category']
|
||||
end
|
||||
|
||||
if (content_inputs = field_template['content']).present?
|
||||
content = CustomWizard::Mapper.new(
|
||||
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
|
||||
}
|
||||
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
|
||||
if content.present? && content[:result].present?
|
||||
if content[:type] == "association"
|
||||
content[:result] = content[:result].map { |item| { id: item[:key], name: item[:value] } }
|
||||
end
|
||||
|
||||
params[:content] = content[:result]
|
||||
end
|
||||
end
|
||||
|
||||
if field_template['index'].present?
|
||||
index = CustomWizard::Mapper.new(
|
||||
inputs: field_template['index'],
|
||||
if field_template["index"].present?
|
||||
index =
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: field_template["index"],
|
||||
user: @wizard.user,
|
||||
data: @wizard.current_submission&.fields_and_meta
|
||||
data: @wizard.current_submission&.fields_and_meta,
|
||||
).perform
|
||||
|
||||
params[:index] = index.to_i unless index.nil?
|
||||
end
|
||||
|
||||
if field_template['description'].present?
|
||||
if field_template["description"].present?
|
||||
params[:description] = mapper.interpolate(
|
||||
field_template['description'],
|
||||
field_template["description"],
|
||||
user: @wizard.user,
|
||||
value: true,
|
||||
wizard: true,
|
||||
template: true
|
||||
template: true,
|
||||
)
|
||||
end
|
||||
|
||||
if field_template['preview_template'].present?
|
||||
preview_template = mapper.interpolate(
|
||||
field_template['preview_template'],
|
||||
if field_template["preview_template"].present?
|
||||
preview_template =
|
||||
mapper.interpolate(
|
||||
field_template["preview_template"],
|
||||
user: @wizard.user,
|
||||
value: true,
|
||||
wizard: true,
|
||||
template: true
|
||||
template: true,
|
||||
)
|
||||
|
||||
params[:preview_template] = PrettyText.cook(preview_template)
|
||||
end
|
||||
|
||||
if field_template['placeholder'].present?
|
||||
if field_template["placeholder"].present?
|
||||
params[:placeholder] = mapper.interpolate(
|
||||
field_template['placeholder'],
|
||||
field_template["placeholder"],
|
||||
user: @wizard.user,
|
||||
value: true,
|
||||
wizard: true,
|
||||
template: true
|
||||
template: true,
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -219,11 +215,11 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
def prefill_field(field_template, step_template)
|
||||
if (prefill = field_template['prefill']).present?
|
||||
if (prefill = field_template["prefill"]).present?
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: prefill,
|
||||
user: @wizard.user,
|
||||
data: @wizard.current_submission&.fields_and_meta
|
||||
data: @wizard.current_submission&.fields_and_meta,
|
||||
).perform
|
||||
end
|
||||
end
|
||||
|
@ -231,13 +227,11 @@ class CustomWizard::Builder
|
|||
def check_if_permitted(step, step_template)
|
||||
step.permitted = true
|
||||
|
||||
if step_template['required_data']
|
||||
step = ensure_required_data(step, step_template)
|
||||
end
|
||||
step = ensure_required_data(step, step_template) if step_template["required_data"]
|
||||
|
||||
if !step.permitted
|
||||
if step_template['required_data_message']
|
||||
step.permitted_message = step_template['required_data_message']
|
||||
if step_template["required_data_message"]
|
||||
step.permitted_message = step_template["required_data_message"]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -245,17 +239,18 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
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]
|
||||
end
|
||||
|
||||
if step_template['description']
|
||||
step.description = mapper.interpolate(
|
||||
step_template['description'],
|
||||
if step_template["description"]
|
||||
step.description =
|
||||
mapper.interpolate(
|
||||
step_template["description"],
|
||||
user: @wizard.user,
|
||||
value: true,
|
||||
wizard: true,
|
||||
template: true
|
||||
template: true,
|
||||
)
|
||||
step.description = PrettyText.cook(step.description)
|
||||
end
|
||||
|
@ -264,8 +259,8 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
def append_step_fields(step, step_template, build_opts)
|
||||
if step_template['fields'] && step_template['fields'].length
|
||||
step_template['fields'].each do |field_template|
|
||||
if step_template["fields"] && step_template["fields"].length
|
||||
step_template["fields"].each do |field_template|
|
||||
next if !check_condition(field_template)
|
||||
append_field(step, step_template, field_template, build_opts)
|
||||
end
|
||||
|
@ -280,18 +275,18 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
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 = {}
|
||||
submission_key = nil
|
||||
params_key = nil
|
||||
submission = @wizard.current_submission
|
||||
|
||||
permitted_params.each do |pp|
|
||||
pair = pp['pairs'].first
|
||||
params_key = pair['key'].to_sym
|
||||
submission_key = pair['value'].to_sym
|
||||
pair = pp["pairs"].first
|
||||
params_key = pair["key"].to_sym
|
||||
submission_key = pair["value"].to_sym
|
||||
|
||||
if submission_key && params_key && params[params_key].present?
|
||||
submission.permitted_param_keys << submission_key.to_s
|
||||
|
@ -303,19 +298,15 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
def ensure_required_data(step, step_template)
|
||||
step_template['required_data'].each do |required|
|
||||
pairs = required['pairs'].select do |pair|
|
||||
pair['key'].present? && pair['value'].present?
|
||||
end
|
||||
step_template["required_data"].each do |required|
|
||||
pairs = required["pairs"].select { |pair| pair["key"].present? && pair["value"].present? }
|
||||
|
||||
if pairs.any? && !@wizard.current_submission.present?
|
||||
step.permitted = false
|
||||
break
|
||||
end
|
||||
|
||||
pairs.each do |pair|
|
||||
pair['key'] = @wizard.current_submission.fields[pair['key']]
|
||||
end
|
||||
pairs.each { |pair| pair["key"] = @wizard.current_submission.fields[pair["key"]] }
|
||||
|
||||
if !mapper.validate_pairs(pairs)
|
||||
step.permitted = false
|
||||
|
@ -328,25 +319,22 @@ class CustomWizard::Builder
|
|||
|
||||
def apply_step_handlers
|
||||
CustomWizard::Builder.step_handlers.each do |handler|
|
||||
if handler[:wizard_id] == @wizard.id
|
||||
handler[:block].call(self)
|
||||
end
|
||||
handler[:block].call(self) if handler[:wizard_id] == @wizard.id
|
||||
end
|
||||
end
|
||||
|
||||
def run_step_actions
|
||||
if @template.actions.present?
|
||||
@template.actions.each do |action_template|
|
||||
if action_template['run_after'] === updater.step.id
|
||||
result = CustomWizard::Action.new(
|
||||
if action_template["run_after"] === updater.step.id
|
||||
result =
|
||||
CustomWizard::Action.new(
|
||||
action: action_template,
|
||||
wizard: @wizard,
|
||||
submission: @submission
|
||||
submission: @submission,
|
||||
).perform
|
||||
|
||||
if result.success?
|
||||
@submission = result.submission
|
||||
end
|
||||
@submission = result.submission if result.success?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,20 +6,20 @@ class ::CustomWizard::CustomField
|
|||
|
||||
attr_reader :id
|
||||
|
||||
ATTRS ||= ["name", "klass", "type", "serializers"]
|
||||
REQUIRED ||= ["name", "klass", "type"]
|
||||
ATTRS ||= %w[name klass type serializers]
|
||||
REQUIRED ||= %w[name klass type]
|
||||
NAMESPACE ||= "custom_wizard_custom_fields"
|
||||
NAME_MIN_LENGTH ||= 3
|
||||
|
||||
CLASSES ||= {
|
||||
topic: ["topic_view", "topic_list_item"],
|
||||
topic: %w[topic_view topic_list_item],
|
||||
group: ["basic_group"],
|
||||
category: ["basic_category"],
|
||||
post: ["post"]
|
||||
post: ["post"],
|
||||
}
|
||||
|
||||
TYPES ||= ["string", "boolean", "integer", "json"]
|
||||
LIST_CACHE_KEY ||= 'custom_field_list'
|
||||
TYPES ||= %w[string boolean integer json]
|
||||
LIST_CACHE_KEY ||= "custom_field_list"
|
||||
|
||||
def self.serializers
|
||||
CLASSES.values.flatten.uniq
|
||||
|
@ -34,9 +34,7 @@ class ::CustomWizard::CustomField
|
|||
|
||||
value = data[attr]
|
||||
|
||||
if value.present?
|
||||
send("#{attr}=", value)
|
||||
end
|
||||
send("#{attr}=", value) if value.present?
|
||||
end
|
||||
|
||||
@subscription = CustomWizard::Subscription.new
|
||||
|
@ -49,9 +47,7 @@ class ::CustomWizard::CustomField
|
|||
data = {}
|
||||
key = name
|
||||
|
||||
(ATTRS - ['name']).each do |attr|
|
||||
data[attr] = send(attr)
|
||||
end
|
||||
(ATTRS - ["name"]).each { |attr| data[attr] = send(attr) }
|
||||
|
||||
if self.class.save_to_store(id, key, data)
|
||||
self.class.invalidate_cache
|
||||
|
@ -74,39 +70,38 @@ class ::CustomWizard::CustomField
|
|||
break
|
||||
end
|
||||
|
||||
if attr == 'serializers' && !value.is_a?(Array)
|
||||
next
|
||||
end
|
||||
next if attr == "serializers" && !value.is_a?(Array)
|
||||
|
||||
if (attr == 'klass' && CLASSES.keys.exclude?(value.to_sym)) ||
|
||||
(attr == 'serializers' && CLASSES[klass.to_sym].blank?)
|
||||
if (attr == "klass" && CLASSES.keys.exclude?(value.to_sym)) ||
|
||||
(attr == "serializers" && CLASSES[klass.to_sym].blank?)
|
||||
add_error(I18n.t("#{i18n_key}.unsupported_class", class: value))
|
||||
next
|
||||
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))
|
||||
end
|
||||
|
||||
if attr == 'serializers' && (unsupported = value - CLASSES[klass.to_sym]).length > 0
|
||||
add_error(I18n.t("#{i18n_key}.unsupported_serializers",
|
||||
if attr == "serializers" && (unsupported = value - CLASSES[klass.to_sym]).length > 0
|
||||
add_error(
|
||||
I18n.t(
|
||||
"#{i18n_key}.unsupported_serializers",
|
||||
class: klass,
|
||||
serializers: unsupported.join(", ")
|
||||
))
|
||||
serializers: unsupported.join(", "),
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
if attr == 'type' && TYPES.exclude?(value)
|
||||
if attr == "type" && TYPES.exclude?(value)
|
||||
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
|
||||
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))
|
||||
end
|
||||
|
||||
if attr == 'name'
|
||||
unless value.is_a?(String)
|
||||
add_error(I18n.t("#{i18n_key}.name_invalid", name: value))
|
||||
end
|
||||
if attr == "name"
|
||||
add_error(I18n.t("#{i18n_key}.name_invalid", name: value)) unless value.is_a?(String)
|
||||
|
||||
if value.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
|
||||
|
||||
begin
|
||||
@name = value.parameterize(separator: '_')
|
||||
rescue
|
||||
@name = value.parameterize(separator: "_")
|
||||
rescue StandardError
|
||||
add_error(I18n.t("#{i18n_key}.name_invalid", name: value))
|
||||
end
|
||||
end
|
||||
|
@ -134,16 +129,15 @@ class ::CustomWizard::CustomField
|
|||
end
|
||||
|
||||
def self.list
|
||||
PluginStoreRow.where(plugin_name: NAMESPACE).map do |record|
|
||||
create_from_store(record)
|
||||
end
|
||||
PluginStoreRow.where(plugin_name: NAMESPACE).map { |record| create_from_store(record) }
|
||||
end
|
||||
|
||||
def self.cached_list
|
||||
@custom_wizard_cached_fields ||= ::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do
|
||||
PluginStoreRow.where(plugin_name: NAMESPACE).map do |record|
|
||||
create_from_store(record).as_json.with_indifferent_access
|
||||
end
|
||||
@custom_wizard_cached_fields ||=
|
||||
::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do
|
||||
PluginStoreRow
|
||||
.where(plugin_name: NAMESPACE)
|
||||
.map { |record| create_from_store(record).as_json.with_indifferent_access }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -234,17 +228,12 @@ class ::CustomWizard::CustomField
|
|||
external = []
|
||||
|
||||
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?
|
||||
meta_data.each do |name, data|
|
||||
unless list.any? { |field| field.name === name }
|
||||
field = new(
|
||||
'external',
|
||||
name: name,
|
||||
klass: klass,
|
||||
type: data.type
|
||||
)
|
||||
field = new("external", name: name, klass: klass, type: data.type)
|
||||
external.push(field)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ::CustomWizard
|
||||
PLUGIN_NAME ||= 'custom_wizard'
|
||||
PLUGIN_NAME ||= "custom_wizard"
|
||||
|
||||
class Engine < ::Rails::Engine
|
||||
engine_name PLUGIN_NAME
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
module CustomWizard
|
||||
class SprocketsFileNotFound < StandardError; end
|
||||
class SprocketsEmptyPath < StandardError; end
|
||||
class SprocketsFileNotFound < StandardError
|
||||
end
|
||||
|
||||
class SprocketsEmptyPath < StandardError
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,11 +3,7 @@ module CustomWizardCustomFieldPreloader
|
|||
def preload_custom_fields(objects, fields)
|
||||
if objects.present? && cw_fields_enabled?
|
||||
@cw_klass = objects.first.class.name.underscore
|
||||
if cw_fields.any?
|
||||
cw_fields.each do |field|
|
||||
fields << field[:name]
|
||||
end
|
||||
end
|
||||
cw_fields.each { |field| fields << field[:name] } if cw_fields.any?
|
||||
end
|
||||
super(objects, fields)
|
||||
end
|
||||
|
|
|
@ -31,10 +31,11 @@ module CustomWizardCustomFieldSerializer
|
|||
end
|
||||
|
||||
def get_cw_class
|
||||
self.class.ancestors.map do |klass|
|
||||
klass.to_s.underscore.gsub("_serializer", "")
|
||||
end.select do |klass|
|
||||
CustomWizard::CustomField.serializers.include?(klass)
|
||||
end.first
|
||||
self
|
||||
.class
|
||||
.ancestors
|
||||
.map { |klass| klass.to_s.underscore.gsub("_serializer", "") }
|
||||
.select { |klass| CustomWizard::CustomField.serializers.include?(klass) }
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,9 +4,12 @@ module CustomWizardDiscourseTagging
|
|||
def filter_allowed_tags(guardian, opts = {})
|
||||
if opts[:for_input].respond_to?(:dig) && (groups = opts.dig(:for_input, :groups)).present?
|
||||
tag_group_array = groups.split(",")
|
||||
filtered_tags = TagGroup.includes(:tags).where(name: tag_group_array).map do |tag_group|
|
||||
tag_group.tags.pluck(:name)
|
||||
end.flatten
|
||||
filtered_tags =
|
||||
TagGroup
|
||||
.includes(:tags)
|
||||
.where(name: tag_group_array)
|
||||
.map { |tag_group| tag_group.tags.pluck(:name) }
|
||||
.flatten
|
||||
|
||||
opts[:only_tag_names] ||= []
|
||||
opts[:only_tag_names].push(*filtered_tags)
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
module ExtraLocalesControllerCustomWizard
|
||||
private def valid_bundle?(bundle)
|
||||
super || begin
|
||||
return false unless bundle =~ /wizard/ && request.referer =~ /\/w\//
|
||||
super ||
|
||||
begin
|
||||
return false unless bundle =~ /wizard/ && request.referer =~ %r{/w/}
|
||||
path = URI(request.referer).path
|
||||
wizard_path = path.split('/w/').last
|
||||
wizard_id = wizard_path.split('/').first
|
||||
wizard_path = path.split("/w/").last
|
||||
wizard_id = wizard_path.split("/").first
|
||||
return true if wizard_id == "qunit"
|
||||
CustomWizard::Template.exists?(wizard_id.underscore)
|
||||
end
|
||||
|
|
|
@ -8,9 +8,7 @@ module CustomWizardGuardian
|
|||
def wizard_can_edit_topic?(topic)
|
||||
created_by_wizard = !!topic.wizard_submission_id
|
||||
(
|
||||
is_my_own?(topic) &&
|
||||
created_by_wizard &&
|
||||
can_see_topic?(topic) &&
|
||||
is_my_own?(topic) && created_by_wizard && can_see_topic?(topic) &&
|
||||
can_create_post_on_topic?(topic)
|
||||
)
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ module InvitesControllerCustomWizard
|
|||
if ::Wizard.user_requires_completion?(@user)
|
||||
wizard_id = @user.redirect_to_wizard
|
||||
|
||||
if wizard_id && url != '/'
|
||||
if wizard_id && url != "/"
|
||||
CustomWizard::Wizard.set_wizard_redirect(@user, wizard_id, url)
|
||||
url = "/w/#{wizard_id.dasherize}"
|
||||
end
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
module CustomWizardUsersController
|
||||
def account_created
|
||||
if current_user.present? &&
|
||||
(wizard = CustomWizard::Wizard.after_signup(current_user))
|
||||
if current_user.present? && (wizard = CustomWizard::Wizard.after_signup(current_user))
|
||||
return redirect_to "/w/#{wizard.id.dasherize}"
|
||||
end
|
||||
super
|
||||
|
|
|
@ -27,12 +27,9 @@ class CustomWizard::Field
|
|||
:preview_template,
|
||||
:placeholder
|
||||
|
||||
attr_accessor :index,
|
||||
:step
|
||||
attr_accessor :index, :step
|
||||
|
||||
REQUIRES_USER = %w[
|
||||
upload
|
||||
]
|
||||
REQUIRES_USER = %w[upload]
|
||||
|
||||
def initialize(attrs)
|
||||
@raw = attrs || {}
|
||||
|
@ -64,9 +61,7 @@ class CustomWizard::Field
|
|||
end
|
||||
|
||||
def default_value
|
||||
if @type == 'checkbox'
|
||||
false
|
||||
end
|
||||
false if @type == "checkbox"
|
||||
end
|
||||
|
||||
def self.types
|
||||
|
@ -77,82 +72,90 @@ class CustomWizard::Field
|
|||
prefill: nil,
|
||||
char_counter: nil,
|
||||
validations: nil,
|
||||
placeholder: nil
|
||||
placeholder: nil,
|
||||
},
|
||||
textarea: {
|
||||
min_length: nil,
|
||||
max_length: nil,
|
||||
prefill: nil,
|
||||
char_counter: nil,
|
||||
placeholder: nil
|
||||
placeholder: nil,
|
||||
},
|
||||
composer: {
|
||||
min_length: nil,
|
||||
max_length: nil,
|
||||
char_counter: nil,
|
||||
placeholder: nil
|
||||
placeholder: nil,
|
||||
},
|
||||
text_only: {
|
||||
},
|
||||
text_only: {},
|
||||
composer_preview: {
|
||||
preview_template: nil,
|
||||
},
|
||||
date: {
|
||||
format: "YYYY-MM-DD"
|
||||
format: "YYYY-MM-DD",
|
||||
},
|
||||
time: {
|
||||
format: "HH:mm"
|
||||
format: "HH:mm",
|
||||
},
|
||||
date_time: {
|
||||
format: ""
|
||||
format: "",
|
||||
},
|
||||
number: {
|
||||
},
|
||||
checkbox: {
|
||||
},
|
||||
number: {},
|
||||
checkbox: {},
|
||||
url: {
|
||||
min_length: nil
|
||||
min_length: nil,
|
||||
},
|
||||
upload: {
|
||||
file_types: '.jpg,.jpeg,.png'
|
||||
file_types: ".jpg,.jpeg,.png",
|
||||
},
|
||||
dropdown: {
|
||||
prefill: nil,
|
||||
content: nil
|
||||
content: nil,
|
||||
},
|
||||
tag: {
|
||||
limit: nil,
|
||||
prefill: nil,
|
||||
content: nil,
|
||||
tag_groups: nil,
|
||||
can_create_tag: false
|
||||
can_create_tag: false,
|
||||
},
|
||||
category: {
|
||||
limit: 1,
|
||||
property: 'id',
|
||||
property: "id",
|
||||
prefill: nil,
|
||||
content: nil
|
||||
content: nil,
|
||||
},
|
||||
topic: {
|
||||
limit: 1,
|
||||
prefill: nil,
|
||||
content: nil,
|
||||
category: nil
|
||||
category: nil,
|
||||
},
|
||||
group: {
|
||||
prefill: nil,
|
||||
content: nil
|
||||
content: nil,
|
||||
},
|
||||
user_selector: {
|
||||
},
|
||||
user_selector: {}
|
||||
}
|
||||
end
|
||||
|
||||
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 ||= {}
|
||||
end
|
||||
|
||||
def self.register(type, plugin = nil, opts = {}, legacy_opts = {})
|
||||
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
|
||||
opts = legacy_opts
|
||||
|
|
|
@ -8,30 +8,28 @@ class CustomWizard::Log
|
|||
PAGE_LIMIT = 100
|
||||
|
||||
def initialize(attrs)
|
||||
@date = attrs['date']
|
||||
@action = attrs['action']
|
||||
@message = attrs['message']
|
||||
@wizard_id = attrs['wizard_id']
|
||||
@username = attrs['username']
|
||||
@date = attrs["date"]
|
||||
@action = attrs["action"]
|
||||
@message = attrs["message"]
|
||||
@wizard_id = attrs["wizard_id"]
|
||||
@username = attrs["username"]
|
||||
end
|
||||
|
||||
def self.create(wizard_id, action, username, message, date = Time.now)
|
||||
log_id = SecureRandom.hex(12)
|
||||
|
||||
PluginStore.set('custom_wizard_log',
|
||||
PluginStore.set(
|
||||
"custom_wizard_log",
|
||||
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
|
||||
|
||||
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.order("value::json->>'date' DESC")
|
||||
end
|
||||
|
@ -43,9 +41,7 @@ class CustomWizard::Log
|
|||
|
||||
result = OpenStruct.new(logs: [], total: nil)
|
||||
result.total = logs.size
|
||||
result.logs = logs.limit(limit)
|
||||
.offset(page * limit)
|
||||
.map { |r| self.new(JSON.parse(r.value)) }
|
||||
result.logs = logs.limit(limit).offset(page * limit).map { |r| self.new(JSON.parse(r.value)) }
|
||||
|
||||
result
|
||||
end
|
||||
|
|
|
@ -2,45 +2,29 @@
|
|||
class CustomWizard::Mapper
|
||||
attr_accessor :inputs, :data, :user
|
||||
|
||||
USER_FIELDS = [
|
||||
'name',
|
||||
'username',
|
||||
'date_of_birth',
|
||||
'title',
|
||||
'locale',
|
||||
'trust_level',
|
||||
'email'
|
||||
]
|
||||
USER_FIELDS = %w[name username date_of_birth title locale trust_level email]
|
||||
|
||||
USER_OPTION_FIELDS = [
|
||||
'email_level',
|
||||
'email_messages_level',
|
||||
'email_digests'
|
||||
]
|
||||
USER_OPTION_FIELDS = %w[email_level email_messages_level email_digests]
|
||||
|
||||
PROFILE_FIELDS = [
|
||||
'location',
|
||||
'website',
|
||||
'bio_raw'
|
||||
]
|
||||
PROFILE_FIELDS = %w[location website bio_raw]
|
||||
|
||||
def self.user_fields
|
||||
USER_FIELDS + USER_OPTION_FIELDS + PROFILE_FIELDS
|
||||
end
|
||||
|
||||
OPERATORS = {
|
||||
equal: '==',
|
||||
equal: "==",
|
||||
not_equal: "!=",
|
||||
greater: '>',
|
||||
less: '<',
|
||||
greater_or_equal: '>=',
|
||||
less_or_equal: '<=',
|
||||
regex: '=~',
|
||||
greater: ">",
|
||||
less: "<",
|
||||
greater_or_equal: ">=",
|
||||
less_or_equal: "<=",
|
||||
regex: "=~",
|
||||
is: {
|
||||
present: "present?",
|
||||
true: "==",
|
||||
false: "=="
|
||||
}
|
||||
false: "==",
|
||||
},
|
||||
}
|
||||
|
||||
def initialize(params)
|
||||
|
@ -55,12 +39,12 @@ class CustomWizard::Mapper
|
|||
perform_result = multiple ? [] : nil
|
||||
|
||||
inputs.each do |input|
|
||||
input_type = input['type']
|
||||
pairs = input['pairs']
|
||||
input_type = input["type"]
|
||||
pairs = input["pairs"]
|
||||
|
||||
if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment'
|
||||
output = input['output']
|
||||
output_type = input['output_type']
|
||||
if (input_type === "conditional" && validate_pairs(pairs)) || input_type === "assignment"
|
||||
output = input["output"]
|
||||
output_type = input["output_type"]
|
||||
|
||||
result = build_result(map_field(output, output_type), input_type)
|
||||
|
||||
|
@ -72,7 +56,7 @@ class CustomWizard::Mapper
|
|||
end
|
||||
end
|
||||
|
||||
if input_type === 'validation'
|
||||
if input_type === "validation"
|
||||
result = build_result(validate_pairs(pairs), input_type)
|
||||
|
||||
if multiple
|
||||
|
@ -83,7 +67,7 @@ class CustomWizard::Mapper
|
|||
end
|
||||
end
|
||||
|
||||
if input_type === 'association'
|
||||
if input_type === "association"
|
||||
result = build_result(map_pairs(pairs), input_type)
|
||||
|
||||
if multiple
|
||||
|
@ -100,10 +84,7 @@ class CustomWizard::Mapper
|
|||
|
||||
def build_result(result, type)
|
||||
if @opts[:with_type]
|
||||
{
|
||||
type: type,
|
||||
result: result
|
||||
}
|
||||
{ type: type, result: result }
|
||||
else
|
||||
result
|
||||
end
|
||||
|
@ -111,10 +92,10 @@ class CustomWizard::Mapper
|
|||
|
||||
def validate_pairs(pairs)
|
||||
pairs.all? do |pair|
|
||||
connector = pair['connector']
|
||||
connector = pair["connector"]
|
||||
operator = map_operator(connector)
|
||||
key = map_field(pair['key'], pair['key_type'])
|
||||
value = cast_value(map_field(pair['value'], pair['value_type']), key, connector)
|
||||
key = map_field(pair["key"], pair["key_type"])
|
||||
value = cast_value(map_field(pair["value"], pair["value_type"]), key, connector)
|
||||
begin
|
||||
validation_result(key, value, operator)
|
||||
rescue NoMethodError
|
||||
|
@ -124,7 +105,7 @@ class CustomWizard::Mapper
|
|||
end
|
||||
|
||||
def cast_value(value, key, connector)
|
||||
if connector == 'regex'
|
||||
if connector == "regex"
|
||||
Regexp.new(value)
|
||||
else
|
||||
if key.is_a?(String)
|
||||
|
@ -143,7 +124,7 @@ class CustomWizard::Mapper
|
|||
if operator.is_a?(Hash) && (operator = operator[value.to_sym]).present?
|
||||
if value == "present"
|
||||
result = key.public_send(operator)
|
||||
elsif ["true", "false"].include?(value)
|
||||
elsif %w[true false].include?(value)
|
||||
result = bool(key).public_send(operator, bool(value))
|
||||
end
|
||||
elsif [key, value, operator].all? { |i| !i.nil? }
|
||||
|
@ -152,7 +133,7 @@ class CustomWizard::Mapper
|
|||
result = false
|
||||
end
|
||||
|
||||
if operator == '=~'
|
||||
if operator == "=~"
|
||||
result.nil? ? false : true
|
||||
else
|
||||
result
|
||||
|
@ -163,22 +144,17 @@ class CustomWizard::Mapper
|
|||
result = []
|
||||
|
||||
pairs.each do |pair|
|
||||
key = map_field(pair['key'], pair['key_type'])
|
||||
value = map_field(pair['value'], pair['value_type'])
|
||||
key = map_field(pair["key"], pair["key_type"])
|
||||
value = map_field(pair["value"], pair["value_type"])
|
||||
|
||||
if key && value
|
||||
result.push(
|
||||
key: key,
|
||||
value: value
|
||||
)
|
||||
end
|
||||
result.push(key: key, value: value) if key && value
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def map_operator(connector)
|
||||
OPERATORS[connector.to_sym] || '=='
|
||||
OPERATORS[connector.to_sym] || "=="
|
||||
end
|
||||
|
||||
def map_field(value, type)
|
||||
|
@ -214,7 +190,7 @@ class CustomWizard::Mapper
|
|||
user.send(value)
|
||||
elsif USER_OPTION_FIELDS.include?(value)
|
||||
user.user_option.send(value)
|
||||
elsif value.include?('avatar')
|
||||
elsif value.include?("avatar")
|
||||
get_avatar_url(value)
|
||||
else
|
||||
nil
|
||||
|
@ -223,7 +199,7 @@ class CustomWizard::Mapper
|
|||
|
||||
def map_user_field_options(value)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
@ -232,22 +208,18 @@ class CustomWizard::Mapper
|
|||
def interpolate(string, opts = { user: true, wizard: true, value: true, template: false })
|
||||
return string if string.blank? || string.frozen?
|
||||
|
||||
if opts[:user] && @user.present?
|
||||
string.gsub!(/u\{(.*?)\}/) { |match| map_user_field($1) || '' }
|
||||
end
|
||||
string.gsub!(/u\{(.*?)\}/) { |match| map_user_field($1) || "" } if opts[:user] && @user.present?
|
||||
|
||||
if opts[:wizard]
|
||||
string.gsub!(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split('.')]) || '' }
|
||||
end
|
||||
string.gsub!(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split(".")]) || "" } if opts[:wizard]
|
||||
|
||||
if opts[:value]
|
||||
string.gsub!(/v\{(.*?)\}/) do |match|
|
||||
attrs = $1.split(':')
|
||||
attrs = $1.split(":")
|
||||
key = attrs.first
|
||||
format = attrs.last if attrs.length > 1
|
||||
result = ''
|
||||
result = ""
|
||||
|
||||
if key == 'time'
|
||||
if key == "time"
|
||||
time_format = format.present? ? format : "%B %-d, %Y"
|
||||
result = Time.now.strftime(time_format)
|
||||
end
|
||||
|
@ -281,10 +253,10 @@ class CustomWizard::Mapper
|
|||
end
|
||||
|
||||
def get_avatar_url(value)
|
||||
parts = value.split('.')
|
||||
parts = value.split(".")
|
||||
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
|
||||
else
|
||||
user.avatar_template_url.gsub("{size}", parts.last)
|
||||
|
|
|
@ -8,7 +8,7 @@ class CustomWizard::RealtimeValidation
|
|||
types: [:text],
|
||||
component: "similar-topics-validator",
|
||||
backend: true,
|
||||
required_params: []
|
||||
}
|
||||
required_params: [],
|
||||
},
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
class CustomWizard::RealtimeValidation::Result
|
||||
attr_accessor :type,
|
||||
:items,
|
||||
:serializer_opts
|
||||
attr_accessor :type, :items, :serializer_opts
|
||||
|
||||
def initialize(type)
|
||||
@type = type
|
||||
|
|
|
@ -27,9 +27,7 @@ class CustomWizard::RealtimeValidation::SimilarTopics
|
|||
|
||||
result = CustomWizard::RealtimeValidation::Result.new(:similar_topic)
|
||||
|
||||
if title.length < SiteSetting.min_title_similar_length
|
||||
return result
|
||||
end
|
||||
return result if title.length < SiteSetting.min_title_similar_length
|
||||
|
||||
topics = Topic.similar_to(title, raw, user).to_a
|
||||
topics.select! { |t| categories.include?(t.category.id.to_s) } if categories.present?
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
class CustomWizard::Step
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
attr_reader :id,
|
||||
:updater
|
||||
attr_reader :id, :updater
|
||||
|
||||
attr_accessor :index,
|
||||
:title,
|
||||
|
|
|
@ -14,18 +14,14 @@ class CustomWizard::StepUpdater
|
|||
end
|
||||
|
||||
def update
|
||||
if SiteSetting.custom_wizard_enabled &&
|
||||
@step.present? &&
|
||||
@step.updater.present? &&
|
||||
success?
|
||||
|
||||
if SiteSetting.custom_wizard_enabled && @step.present? && @step.updater.present? && success?
|
||||
@step.updater.call(self)
|
||||
|
||||
CustomWizard::UserHistory.create(
|
||||
action: CustomWizard::UserHistory.actions[:step],
|
||||
actor_id: @wizard.actor_id,
|
||||
context: @wizard.id,
|
||||
subject: @step.id
|
||||
subject: @step.id,
|
||||
)
|
||||
else
|
||||
false
|
||||
|
|
|
@ -4,31 +4,25 @@ class CustomWizard::Submission
|
|||
|
||||
PAGE_LIMIT = 50
|
||||
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,
|
||||
:wizard
|
||||
attr_reader :id, :wizard
|
||||
|
||||
attr_accessor :fields,
|
||||
:permitted_param_keys
|
||||
attr_accessor :fields, :permitted_param_keys
|
||||
|
||||
META.each do |attr|
|
||||
class_eval { attr_accessor attr }
|
||||
end
|
||||
META.each { |attr| class_eval { attr_accessor attr } }
|
||||
|
||||
def initialize(wizard, data = {})
|
||||
@wizard = wizard
|
||||
|
||||
data = (data || {}).with_indifferent_access
|
||||
@id = data['id'] || SecureRandom.hex(12)
|
||||
non_field_keys = META + ['id']
|
||||
@id = data["id"] || SecureRandom.hex(12)
|
||||
non_field_keys = META + ["id"]
|
||||
@fields = data.except(*non_field_keys) || {}
|
||||
|
||||
META.each do |attr|
|
||||
send("#{attr}=", data[attr]) if data[attr]
|
||||
end
|
||||
META.each { |attr| send("#{attr}=", data[attr]) if data[attr] }
|
||||
|
||||
@permitted_param_keys = data['permitted_param_keys'] || []
|
||||
@permitted_param_keys = data["permitted_param_keys"] || []
|
||||
end
|
||||
|
||||
def save
|
||||
|
@ -49,8 +43,7 @@ class CustomWizard::Submission
|
|||
end
|
||||
|
||||
def validate_field_key(key)
|
||||
wizard.field_ids.include?(key) ||
|
||||
wizard.action_ids.include?(key) ||
|
||||
wizard.field_ids.include?(key) || wizard.action_ids.include?(key) ||
|
||||
permitted_param_keys.include?(key)
|
||||
end
|
||||
|
||||
|
@ -71,9 +64,7 @@ class CustomWizard::Submission
|
|||
end
|
||||
|
||||
def data_to_save(submission)
|
||||
data = {
|
||||
id: submission.id
|
||||
}
|
||||
data = { id: submission.id }
|
||||
|
||||
data.merge!(submission.fields_and_meta)
|
||||
|
||||
|
@ -103,16 +94,21 @@ class CustomWizard::Submission
|
|||
|
||||
def self.cleanup_incomplete_submissions(wizard)
|
||||
all_submissions = list(wizard)
|
||||
sorted_submissions = all_submissions.submissions.sort_by do |submission|
|
||||
zero_epoch_time = DateTime.strptime("0", '%s')
|
||||
sorted_submissions =
|
||||
all_submissions
|
||||
.submissions
|
||||
.sort_by do |submission|
|
||||
zero_epoch_time = DateTime.strptime("0", "%s")
|
||||
[
|
||||
submission.submitted_at ? Time.iso8601(submission.submitted_at) : zero_epoch_time,
|
||||
submission.updated_at ? Time.iso8601(submission.updated_at) : zero_epoch_time
|
||||
submission.updated_at ? Time.iso8601(submission.updated_at) : zero_epoch_time,
|
||||
]
|
||||
end.reverse
|
||||
end
|
||||
.reverse
|
||||
|
||||
has_incomplete = false
|
||||
valid_submissions = sorted_submissions.select do |submission|
|
||||
valid_submissions =
|
||||
sorted_submissions.select do |submission|
|
||||
to_be_included = submission.submitted_at || !has_incomplete
|
||||
has_incomplete = true if !submission.submitted_at
|
||||
|
||||
|
|
|
@ -2,128 +2,129 @@
|
|||
require "discourse_subscription_client"
|
||||
|
||||
class CustomWizard::Subscription
|
||||
PRODUCT_HIERARCHY = %w[
|
||||
community
|
||||
standard
|
||||
business
|
||||
]
|
||||
PRODUCT_HIERARCHY = %w[community standard business]
|
||||
|
||||
def self.attributes
|
||||
{
|
||||
wizard: {
|
||||
required: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
permitted: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*', "!#{CustomWizard::Wizard::GUEST_GROUP_ID}"]
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*", "!#{CustomWizard::Wizard::GUEST_GROUP_ID}"],
|
||||
},
|
||||
restart_on_revisit: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
}
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
},
|
||||
step: {
|
||||
condition: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
required_data: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
permitted_params: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
}
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
},
|
||||
field: {
|
||||
condition: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
type: {
|
||||
none: ['text', 'textarea', 'text_only', 'date', 'time', 'date_time', 'number', 'checkbox', 'dropdown', 'upload'],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
none: %w[text textarea text_only date time date_time number checkbox dropdown upload],
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
realtime_validations: {
|
||||
none: [],
|
||||
standard: ['*'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
}
|
||||
standard: ["*"],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
},
|
||||
action: {
|
||||
type: {
|
||||
none: ['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'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
}
|
||||
none: %w[create_topic update_profile open_composer route_to],
|
||||
standard: %w[
|
||||
create_topic
|
||||
update_profile
|
||||
open_composer
|
||||
route_to
|
||||
send_message
|
||||
watch_categories
|
||||
watch_tags
|
||||
add_to_group
|
||||
],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
},
|
||||
custom_field: {
|
||||
klass: {
|
||||
none: ['topic', 'post'],
|
||||
standard: ['topic', 'post'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
none: %w[topic post],
|
||||
standard: %w[topic post],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
type: {
|
||||
none: ['string', 'boolean', 'integer'],
|
||||
standard: ['string', 'boolean', 'integer'],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
}
|
||||
none: %w[string boolean integer],
|
||||
standard: %w[string boolean integer],
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
},
|
||||
api: {
|
||||
all: {
|
||||
none: [],
|
||||
standard: [],
|
||||
business: ['*'],
|
||||
community: ['*']
|
||||
}
|
||||
}
|
||||
business: ["*"],
|
||||
community: ["*"],
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
attr_accessor :product_id,
|
||||
:product_slug
|
||||
attr_accessor :product_id, :product_slug
|
||||
|
||||
def initialize(update = false)
|
||||
if update
|
||||
::DiscourseSubscriptionClient::Subscriptions.update
|
||||
end
|
||||
::DiscourseSubscriptionClient::Subscriptions.update if update
|
||||
|
||||
result = ::DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard")
|
||||
|
||||
if result&.any?
|
||||
ids_and_slugs = result.subscriptions.map do |subscription|
|
||||
{
|
||||
id: subscription.product_id,
|
||||
slug: result.products[subscription.product_id]
|
||||
}
|
||||
ids_and_slugs =
|
||||
result.subscriptions.map do |subscription|
|
||||
{ id: subscription.product_id, slug: result.products[subscription.product_id] }
|
||||
end
|
||||
|
||||
id_and_slug = ids_and_slugs.sort do |a, b|
|
||||
PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug])
|
||||
end.first
|
||||
id_and_slug =
|
||||
ids_and_slugs
|
||||
.sort { |a, b| PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug]) }
|
||||
.first
|
||||
|
||||
@product_id = id_and_slug[:id]
|
||||
@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.
|
||||
def self.client_installed?
|
||||
defined?(DiscourseSubscriptionClient) == 'constant' && DiscourseSubscriptionClient.class == Module
|
||||
defined?(DiscourseSubscriptionClient) == "constant" &&
|
||||
DiscourseSubscriptionClient.class == Module
|
||||
end
|
||||
|
||||
def self.subscribed?
|
||||
|
@ -219,10 +221,12 @@ class CustomWizard::Subscription
|
|||
end
|
||||
|
||||
def mapped_output(value)
|
||||
value.reduce([]) do |result, v|
|
||||
value
|
||||
.reduce([]) do |result, v|
|
||||
## We can only validate mapped assignment values at the moment
|
||||
result << v["output"] if v.is_a?(Hash) && v["type"] === "assignment"
|
||||
result
|
||||
end.flatten
|
||||
end
|
||||
.flatten
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,15 +6,12 @@ class CustomWizard::Template
|
|||
AFTER_SIGNUP_CACHE_KEY ||= "after_signup_wizard_ids"
|
||||
AFTER_TIME_CACHE_KEY ||= "after_time_wizard_ids"
|
||||
|
||||
attr_reader :data,
|
||||
:opts,
|
||||
:steps,
|
||||
:actions
|
||||
attr_reader :data, :opts, :steps, :actions
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
@steps = data['steps'] || []
|
||||
@actions = data['actions'] || []
|
||||
@steps = data["steps"] || []
|
||||
@actions = data["actions"] || []
|
||||
end
|
||||
|
||||
def save(opts = {})
|
||||
|
@ -64,7 +61,11 @@ class CustomWizard::Template
|
|||
ensure_wizard_upload_references!(wizard_id)
|
||||
PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id)
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -74,7 +75,7 @@ class CustomWizard::Template
|
|||
end
|
||||
|
||||
def self.exists?(wizard_id)
|
||||
PluginStoreRow.exists?(plugin_name: 'custom_wizard', key: wizard_id)
|
||||
PluginStoreRow.exists?(plugin_name: "custom_wizard", key: wizard_id)
|
||||
end
|
||||
|
||||
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 += " #{query_str}" if query_str
|
||||
|
||||
PluginStoreRow.where(query).order(order)
|
||||
PluginStoreRow
|
||||
.where(query)
|
||||
.order(order)
|
||||
.reduce([]) do |result, record|
|
||||
attrs = JSON.parse(record.value)
|
||||
|
||||
if attrs.present? &&
|
||||
attrs.is_a?(Hash) &&
|
||||
attrs['id'].present? &&
|
||||
attrs['name'].present?
|
||||
|
||||
if attrs.present? && attrs.is_a?(Hash) && attrs["id"].present? && attrs["name"].present?
|
||||
result.push(attrs)
|
||||
end
|
||||
|
||||
|
@ -99,25 +98,24 @@ class CustomWizard::Template
|
|||
end
|
||||
|
||||
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)
|
||||
end
|
||||
Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id) if after_time
|
||||
end
|
||||
|
||||
def self.after_signup_ids
|
||||
::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
|
||||
|
||||
def self.after_time_ids
|
||||
::CustomWizard::Cache.wrap(AFTER_TIME_CACHE_KEY) do
|
||||
list(
|
||||
setting: 'after_time',
|
||||
query_str: "AND (value::json ->> 'after_time_scheduled')::timestamp < '#{Time.now}'::timestamp"
|
||||
).map { |t| t['id'] }
|
||||
setting: "after_time",
|
||||
query_str:
|
||||
"AND (value::json ->> 'after_time_scheduled')::timestamp < '#{Time.now}'::timestamp",
|
||||
).map { |t| t["id"] }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -137,7 +135,7 @@ class CustomWizard::Template
|
|||
UploadReference.ensure_exist!(
|
||||
upload_ids: wizard_upload_ids,
|
||||
target_type: "PluginStoreRow",
|
||||
target_id: wizard_record.id
|
||||
target_id: wizard_record.id,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -151,15 +149,11 @@ class CustomWizard::Template
|
|||
|
||||
def prepare_data
|
||||
@data[:steps].each do |step|
|
||||
if step[:raw_description]
|
||||
step[:description] = step[:raw_description]
|
||||
end
|
||||
step[:description] = step[:raw_description] if step[:raw_description]
|
||||
|
||||
remove_non_mapped_index(step)
|
||||
|
||||
step[:fields].each do |field|
|
||||
remove_non_mapped_index(field)
|
||||
end
|
||||
step[:fields].each { |field| remove_non_mapped_index(field) }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -191,9 +185,7 @@ class CustomWizard::Template
|
|||
end
|
||||
|
||||
def remove_non_mapped_index(object)
|
||||
if !object[:index].is_a?(Array)
|
||||
object.delete(:index)
|
||||
end
|
||||
object.delete(:index) if !object[:index].is_a?(Array)
|
||||
end
|
||||
|
||||
def ensure_wizard_upload_references!
|
||||
|
|
|
@ -15,26 +15,18 @@ class CustomWizard::UserHistory
|
|||
end
|
||||
|
||||
def self.actions
|
||||
@actions ||=
|
||||
Enum.new(
|
||||
step: UserHistory.actions[:custom_wizard_step]
|
||||
)
|
||||
@actions ||= Enum.new(step: UserHistory.actions[:custom_wizard_step])
|
||||
end
|
||||
|
||||
def self.where_opts(actor_id, action, context, subject)
|
||||
opts = {
|
||||
context: context
|
||||
}
|
||||
opts = { context: context }
|
||||
opts[:action] = action if action
|
||||
opts[:subject] = subject if subject
|
||||
add_actor(opts, actor_id)
|
||||
end
|
||||
|
||||
def self.create_opts(actor_id, action, context, subject)
|
||||
opts = {
|
||||
action: action,
|
||||
context: context
|
||||
}
|
||||
opts = { action: action, context: context }
|
||||
opts[:subject] = subject if subject
|
||||
add_actor(opts, actor_id)
|
||||
end
|
||||
|
|
|
@ -48,12 +48,7 @@ class CustomWizard::TemplateValidator
|
|||
end
|
||||
|
||||
def self.required
|
||||
{
|
||||
wizard: ['id', 'name', 'steps'],
|
||||
step: ['id'],
|
||||
field: ['id', 'type'],
|
||||
action: ['id', 'type']
|
||||
}
|
||||
{ wizard: %w[id name steps], step: ["id"], field: %w[id type], action: %w[id type] }
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -71,7 +66,8 @@ class CustomWizard::TemplateValidator
|
|||
value = object[property]
|
||||
|
||||
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
|
||||
|
@ -83,9 +79,9 @@ class CustomWizard::TemplateValidator
|
|||
end
|
||||
|
||||
def validate_guests(object, type)
|
||||
guests_permitted = @data[:permitted] && @data[:permitted].any? do |m|
|
||||
m["output"]&.include?(CustomWizard::Wizard::GUEST_GROUP_ID)
|
||||
end
|
||||
guests_permitted =
|
||||
@data[:permitted] &&
|
||||
@data[:permitted].any? { |m| m["output"]&.include?(CustomWizard::Wizard::GUEST_GROUP_ID) }
|
||||
return unless guests_permitted
|
||||
|
||||
if type === :action && CustomWizard::Action::REQUIRES_USER.include?(object[:type])
|
||||
|
@ -100,11 +96,14 @@ class CustomWizard::TemplateValidator
|
|||
def validate_after_signup
|
||||
return unless ActiveRecord::Type::Boolean.new.cast(@data[:after_signup])
|
||||
|
||||
other_after_signup = CustomWizard::Template.list(setting: 'after_signup')
|
||||
.select { |template| template['id'] != @data[:id] }
|
||||
other_after_signup =
|
||||
CustomWizard::Template
|
||||
.list(setting: "after_signup")
|
||||
.select { |template| template["id"] != @data[:id] }
|
||||
|
||||
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
|
||||
|
||||
|
@ -132,20 +131,16 @@ class CustomWizard::TemplateValidator
|
|||
end
|
||||
|
||||
def validate_liquid_template(object, type)
|
||||
%w[
|
||||
description
|
||||
raw_description
|
||||
placeholder
|
||||
preview_template
|
||||
post_template
|
||||
].each do |field|
|
||||
%w[description raw_description placeholder preview_template post_template].each do |field|
|
||||
if template = object[field]
|
||||
result = is_liquid_template_valid?(template)
|
||||
|
||||
unless "valid" == result
|
||||
error = I18n.t("wizard.validation.liquid_syntax_error",
|
||||
error =
|
||||
I18n.t(
|
||||
"wizard.validation.liquid_syntax_error",
|
||||
attribute: "#{object[:id]}.#{field}",
|
||||
message: result
|
||||
message: result,
|
||||
)
|
||||
errors.add :base, error
|
||||
end
|
||||
|
@ -156,7 +151,7 @@ class CustomWizard::TemplateValidator
|
|||
def is_liquid_template_valid?(template)
|
||||
begin
|
||||
Liquid::Template.parse(template)
|
||||
'valid'
|
||||
"valid"
|
||||
rescue Liquid::SyntaxError => error
|
||||
error.message
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
require 'addressable/uri'
|
||||
require "addressable/uri"
|
||||
|
||||
class ::CustomWizard::UpdateValidator
|
||||
attr_reader :updater
|
||||
|
@ -9,13 +9,11 @@ class ::CustomWizard::UpdateValidator
|
|||
end
|
||||
|
||||
def perform
|
||||
updater.step.fields.each do |field|
|
||||
validate_field(field)
|
||||
end
|
||||
updater.step.fields.each { |field| validate_field(field) }
|
||||
end
|
||||
|
||||
def validate_field(field)
|
||||
return if field.type == 'text_only'
|
||||
return if field.type == "text_only"
|
||||
|
||||
field_id = field.id.to_s
|
||||
value = @updater.submission[field_id]
|
||||
|
@ -29,43 +27,48 @@ class ::CustomWizard::UpdateValidator
|
|||
format = field.format
|
||||
|
||||
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
|
||||
|
||||
if value.is_a?(String) && (stripped_length = value.strip.length) > 0
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
if type === 'checkbox'
|
||||
@updater.submission[field_id] = standardise_boolean(value)
|
||||
@updater.submission[field_id] = standardise_boolean(value) if type === "checkbox"
|
||||
|
||||
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
|
||||
|
||||
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))
|
||||
if %w[date date_time].include?(type) && value.present? && !validate_date(value, format)
|
||||
@updater.errors.add(field_id, I18n.t("wizard.field.invalid_date"))
|
||||
end
|
||||
|
||||
if ['date', 'date_time'].include?(type) && value.present? && !validate_date(value, format)
|
||||
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_date'))
|
||||
end
|
||||
|
||||
if type === 'time' && value.present? && !validate_time(value)
|
||||
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_time'))
|
||||
if type === "time" && value.present? && !validate_time(value)
|
||||
@updater.errors.add(field_id, I18n.t("wizard.field.invalid_time"))
|
||||
end
|
||||
|
||||
self.class.field_validators.each do |validator|
|
||||
if type === validator[:type]
|
||||
validator[:block].call(field, value, @updater)
|
||||
end
|
||||
validator[:block].call(field, value, @updater) if type === validator[:type]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -85,9 +88,10 @@ class ::CustomWizard::UpdateValidator
|
|||
private
|
||||
|
||||
def validate_file_type(value, file_types)
|
||||
file_types.split(',')
|
||||
.map { |t| t.gsub('.', '') }
|
||||
.include?(File.extname(value['original_filename'])[1..-1])
|
||||
file_types
|
||||
.split(",")
|
||||
.map { |t| t.gsub(".", "") }
|
||||
.include?(File.extname(value["original_filename"])[1..-1])
|
||||
end
|
||||
|
||||
def validate_date(value, format)
|
||||
|
@ -104,14 +108,14 @@ class ::CustomWizard::UpdateValidator
|
|||
end
|
||||
|
||||
def is_text_type(field)
|
||||
['text', 'textarea', 'composer'].include? field.type
|
||||
%w[text textarea composer].include? field.type
|
||||
end
|
||||
|
||||
def is_url_type(field)
|
||||
['url'].include? field.type
|
||||
["url"].include? field.type
|
||||
end
|
||||
|
||||
SCHEMES ||= %w(http https)
|
||||
SCHEMES ||= %w[http https]
|
||||
|
||||
def check_if_url(url)
|
||||
parsed = Addressable::URI.parse(url) or return false
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
require_dependency 'wizard/step'
|
||||
require_dependency 'wizard/field'
|
||||
require_dependency 'wizard/step_updater'
|
||||
require_dependency 'wizard/builder'
|
||||
require_dependency "wizard/step"
|
||||
require_dependency "wizard/field"
|
||||
require_dependency "wizard/step_updater"
|
||||
require_dependency "wizard/builder"
|
||||
|
||||
class CustomWizard::Wizard
|
||||
include ActiveModel::SerializerSupport
|
||||
|
@ -47,44 +47,40 @@ class CustomWizard::Wizard
|
|||
|
||||
attrs = attrs.with_indifferent_access
|
||||
|
||||
@id = attrs['id']
|
||||
@name = attrs['name']
|
||||
@background = attrs['background']
|
||||
@save_submissions = cast_bool(attrs['save_submissions'])
|
||||
@multiple_submissions = cast_bool(attrs['multiple_submissions'])
|
||||
@prompt_completion = cast_bool(attrs['prompt_completion'])
|
||||
@restart_on_revisit = cast_bool(attrs['restart_on_revisit'])
|
||||
@resume_on_revisit = cast_bool(attrs['resume_on_revisit'])
|
||||
@after_signup = cast_bool(attrs['after_signup'])
|
||||
@after_time = cast_bool(attrs['after_time'])
|
||||
@after_time_scheduled = attrs['after_time_scheduled']
|
||||
@required = cast_bool(attrs['required'])
|
||||
@permitted = attrs['permitted'] || nil
|
||||
@theme_id = attrs['theme_id']
|
||||
@id = attrs["id"]
|
||||
@name = attrs["name"]
|
||||
@background = attrs["background"]
|
||||
@save_submissions = cast_bool(attrs["save_submissions"])
|
||||
@multiple_submissions = cast_bool(attrs["multiple_submissions"])
|
||||
@prompt_completion = cast_bool(attrs["prompt_completion"])
|
||||
@restart_on_revisit = cast_bool(attrs["restart_on_revisit"])
|
||||
@resume_on_revisit = cast_bool(attrs["resume_on_revisit"])
|
||||
@after_signup = cast_bool(attrs["after_signup"])
|
||||
@after_time = cast_bool(attrs["after_time"])
|
||||
@after_time_scheduled = attrs["after_time_scheduled"]
|
||||
@required = cast_bool(attrs["required"])
|
||||
@permitted = attrs["permitted"] || nil
|
||||
@theme_id = attrs["theme_id"]
|
||||
|
||||
if attrs['theme'].present?
|
||||
theme = ::Theme.find_by(name: attrs['theme'])
|
||||
if attrs["theme"].present?
|
||||
theme = ::Theme.find_by(name: attrs["theme"])
|
||||
@theme_id = theme.id if theme
|
||||
end
|
||||
|
||||
@first_step = nil
|
||||
@steps = []
|
||||
|
||||
if attrs['steps'].present?
|
||||
@step_ids = @all_step_ids = attrs['steps'].map { |s| s['id'] }
|
||||
if attrs["steps"].present?
|
||||
@step_ids = @all_step_ids = attrs["steps"].map { |s| s["id"] }
|
||||
|
||||
@field_ids = []
|
||||
attrs['steps'].each do |step|
|
||||
if step['fields'].present?
|
||||
step['fields'].each do |field|
|
||||
@field_ids << field['id']
|
||||
end
|
||||
end
|
||||
attrs["steps"].each do |step|
|
||||
step["fields"].each { |field| @field_ids << field["id"] } if step["fields"].present?
|
||||
end
|
||||
end
|
||||
|
||||
@actions = attrs['actions'] || []
|
||||
@action_ids = @actions.map { |a| a['id'] }
|
||||
@actions = attrs["actions"] || []
|
||||
@action_ids = @actions.map { |a| a["id"] }
|
||||
@template = attrs
|
||||
end
|
||||
|
||||
|
@ -137,13 +133,9 @@ class CustomWizard::Wizard
|
|||
|
||||
step.index = index
|
||||
|
||||
if index === (steps.length - 1)
|
||||
step.conditional_final_step = true
|
||||
end
|
||||
step.conditional_final_step = true if index === (steps.length - 1)
|
||||
|
||||
if index === (all_step_ids.length - 1)
|
||||
step.last_step = true
|
||||
end
|
||||
step.last_step = true if index === (all_step_ids.length - 1)
|
||||
|
||||
if !@restart_on_revisit && step.previous && step.previous.id === last_completed_step_id
|
||||
@start = step.id
|
||||
|
@ -154,12 +146,16 @@ class CustomWizard::Wizard
|
|||
def last_completed_step_id
|
||||
return nil unless actor_id && unfinished?
|
||||
|
||||
last_completed_step = CustomWizard::UserHistory.where(
|
||||
last_completed_step =
|
||||
CustomWizard::UserHistory
|
||||
.where(
|
||||
actor_id: actor_id,
|
||||
action: CustomWizard::UserHistory.actions[:step],
|
||||
context: id,
|
||||
subject: all_step_ids
|
||||
).order("created_at").last
|
||||
subject: all_step_ids,
|
||||
)
|
||||
.order("created_at")
|
||||
.last
|
||||
|
||||
last_completed_step&.subject
|
||||
end
|
||||
|
@ -178,11 +174,12 @@ class CustomWizard::Wizard
|
|||
return nil unless actor_id
|
||||
return false if last_submission&.submitted?
|
||||
|
||||
most_recent = CustomWizard::UserHistory.where(
|
||||
actor_id: actor_id,
|
||||
action: CustomWizard::UserHistory.actions[:step],
|
||||
context: id,
|
||||
).distinct.order('updated_at DESC').first
|
||||
most_recent =
|
||||
CustomWizard::UserHistory
|
||||
.where(actor_id: actor_id, action: CustomWizard::UserHistory.actions[:step], context: id)
|
||||
.distinct
|
||||
.order("updated_at DESC")
|
||||
.first
|
||||
|
||||
if most_recent && most_recent.subject == "reset"
|
||||
false
|
||||
|
@ -197,10 +194,11 @@ class CustomWizard::Wizard
|
|||
return nil unless actor_id
|
||||
return true if last_submission&.submitted?
|
||||
|
||||
history = CustomWizard::UserHistory.where(
|
||||
history =
|
||||
CustomWizard::UserHistory.where(
|
||||
actor_id: actor_id,
|
||||
action: CustomWizard::UserHistory.actions[:step],
|
||||
context: id
|
||||
context: id,
|
||||
)
|
||||
|
||||
if after_time && multiple_submissions
|
||||
|
@ -216,26 +214,27 @@ class CustomWizard::Wizard
|
|||
return true if user && ((always_allow_admin && user.admin?) || permitted.blank?)
|
||||
return false if !user && permitted.blank?
|
||||
|
||||
mapper = CustomWizard::Mapper.new(
|
||||
mapper =
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: permitted,
|
||||
user: user,
|
||||
opts: {
|
||||
with_type: true,
|
||||
multiple: true
|
||||
}
|
||||
multiple: true,
|
||||
},
|
||||
).perform
|
||||
|
||||
return true if mapper.blank?
|
||||
|
||||
mapper.all? do |m|
|
||||
if !user
|
||||
m[:type] === 'assignment' && [*m[:result]].include?(GUEST_GROUP_ID)
|
||||
m[:type] === "assignment" && [*m[:result]].include?(GUEST_GROUP_ID)
|
||||
else
|
||||
if m[:type] === 'assignment'
|
||||
if m[:type] === "assignment"
|
||||
[*m[:result]].include?(GUEST_GROUP_ID) ||
|
||||
[*m[:result]].include?(Group::AUTO_GROUPS[:everyone]) ||
|
||||
GroupUser.exists?(group_id: m[:result], user_id: user.id)
|
||||
elsif m[:type] === 'validation'
|
||||
elsif m[:type] === "validation"
|
||||
m[:result]
|
||||
else
|
||||
true
|
||||
|
@ -259,7 +258,7 @@ class CustomWizard::Wizard
|
|||
action: CustomWizard::UserHistory.actions[:step],
|
||||
actor_id: actor_id,
|
||||
context: id,
|
||||
subject: "reset"
|
||||
subject: "reset",
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -275,11 +274,9 @@ class CustomWizard::Wizard
|
|||
@action_ids = []
|
||||
|
||||
@actions.each do |action|
|
||||
if action['run_after'].blank? ||
|
||||
action['run_after'] === 'wizard_completion' ||
|
||||
step_ids.include?(action['run_after'])
|
||||
|
||||
@action_ids << action['id']
|
||||
if action["run_after"].blank? || action["run_after"] === "wizard_completion" ||
|
||||
step_ids.include?(action["run_after"])
|
||||
@action_ids << action["id"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -293,7 +290,8 @@ class CustomWizard::Wizard
|
|||
end
|
||||
|
||||
def current_submission
|
||||
@current_submission ||= begin
|
||||
@current_submission ||=
|
||||
begin
|
||||
if submissions.present?
|
||||
unsubmitted = submissions.select { |submission| !submission.submitted_at }
|
||||
unsubmitted.present? ? unsubmitted.first : CustomWizard::Submission.new(self)
|
||||
|
@ -317,9 +315,7 @@ class CustomWizard::Wizard
|
|||
def cleanup_on_skip!
|
||||
remove_user_redirect
|
||||
|
||||
if current_submission.present?
|
||||
current_submission.remove
|
||||
end
|
||||
current_submission.remove if current_submission.present?
|
||||
|
||||
reset
|
||||
end
|
||||
|
@ -328,7 +324,7 @@ class CustomWizard::Wizard
|
|||
return if user.blank?
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
@ -344,42 +340,33 @@ class CustomWizard::Wizard
|
|||
def self.list(user, template_opts = {}, not_completed = false)
|
||||
return [] unless user
|
||||
|
||||
CustomWizard::Template.list(**template_opts).reduce([]) do |result, template|
|
||||
CustomWizard::Template
|
||||
.list(**template_opts)
|
||||
.reduce([]) do |result, template|
|
||||
wizard = new(template, user)
|
||||
result.push(wizard) if wizard.permitted? && (
|
||||
!not_completed || !wizard.completed?
|
||||
)
|
||||
result.push(wizard) if wizard.permitted? && (!not_completed || !wizard.completed?)
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def self.after_signup(user)
|
||||
wizards = list(
|
||||
wizards =
|
||||
list(
|
||||
user,
|
||||
{
|
||||
setting: 'after_signup',
|
||||
order: "(value::json ->> 'permitted') IS NOT NULL DESC"
|
||||
}
|
||||
{ setting: "after_signup", order: "(value::json ->> 'permitted') IS NOT NULL DESC" },
|
||||
)
|
||||
wizards.any? ? wizards.first : false
|
||||
end
|
||||
|
||||
def self.prompt_completion(user)
|
||||
wizards = list(
|
||||
wizards =
|
||||
list(
|
||||
user,
|
||||
{
|
||||
setting: 'prompt_completion',
|
||||
order: "(value::json ->> 'permitted') IS NOT NULL DESC"
|
||||
},
|
||||
true
|
||||
{ setting: "prompt_completion", order: "(value::json ->> 'permitted') IS NOT NULL DESC" },
|
||||
true,
|
||||
)
|
||||
if wizards.any?
|
||||
wizards.map do |w|
|
||||
{
|
||||
id: w.id,
|
||||
name: w.name
|
||||
}
|
||||
end
|
||||
wizards.map { |w| { id: w.id, name: w.name } }
|
||||
else
|
||||
false
|
||||
end
|
||||
|
@ -389,7 +376,7 @@ class CustomWizard::Wizard
|
|||
wizard = self.create(wizard_id, user)
|
||||
|
||||
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)
|
||||
else
|
||||
false
|
||||
|
|
|
@ -13,7 +13,7 @@ module DiscoursePluginStatistics
|
|||
step: {
|
||||
required_data: 0,
|
||||
permitted_params: 0,
|
||||
force_final: 0
|
||||
force_final: 0,
|
||||
},
|
||||
field: {
|
||||
condition: 0,
|
||||
|
@ -37,7 +37,7 @@ module DiscoursePluginStatistics
|
|||
group: 0,
|
||||
user_selector: 0,
|
||||
},
|
||||
realtime_validations: 0
|
||||
realtime_validations: 0,
|
||||
},
|
||||
action: {
|
||||
type: {
|
||||
|
@ -52,12 +52,13 @@ module DiscoursePluginStatistics
|
|||
add_to_group: 0,
|
||||
create_group: 0,
|
||||
create_category: 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
increment_feature_count = lambda do |type, key, value|
|
||||
if key == 'type'
|
||||
increment_feature_count =
|
||||
lambda do |type, key, value|
|
||||
if key == "type"
|
||||
if !subscription_features[type.to_sym][:type][value.to_sym].nil?
|
||||
subscription_features[type.to_sym][:type][value.to_sym] += 1
|
||||
end
|
||||
|
@ -69,30 +70,22 @@ module DiscoursePluginStatistics
|
|||
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)
|
||||
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
|
||||
template['actions'].each do |action|
|
||||
action.each do |key, value|
|
||||
increment_feature_count.call(:action, key, value)
|
||||
end
|
||||
template["actions"].each do |action|
|
||||
action.each { |key, value| increment_feature_count.call(:action, key, value) }
|
||||
end
|
||||
end
|
||||
|
||||
{
|
||||
total_wizards: CustomWizard::Template.list.size,
|
||||
subscription_type: CustomWizard::Subscription.type.to_s,
|
||||
subscription_features: subscription_features
|
||||
subscription_features: subscription_features,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
58
plugin.rb
58
plugin.rb
|
@ -1,19 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
# name: discourse-custom-wizard
|
||||
# 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
|
||||
# url: https://github.com/paviliondev/discourse-custom-wizard
|
||||
# contact_emails: development@pavilion.tech
|
||||
# subscription_url: https://coop.pavilion.tech
|
||||
# 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_plugin_statistics', '0.1.0.pre7', require: true
|
||||
register_asset 'stylesheets/common/admin.scss'
|
||||
register_asset 'stylesheets/common/wizard.scss'
|
||||
register_svg_icon 'pavilion-logo'
|
||||
gem "discourse_plugin_statistics", "0.1.0.pre7", require: true
|
||||
register_asset "stylesheets/common/admin.scss"
|
||||
register_asset "stylesheets/common/wizard.scss"
|
||||
register_svg_icon "pavilion-logo"
|
||||
register_svg_icon "hat-wizard"
|
||||
|
||||
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/extension.rb
|
||||
../lib/custom_wizard/extensions/discourse_tagging.rb
|
||||
].each do |path|
|
||||
load File.expand_path(path, __FILE__)
|
||||
end
|
||||
].each { |path| load File.expand_path(path, __FILE__) }
|
||||
|
||||
Liquid::Template.error_mode = :strict
|
||||
|
||||
# preloaded category custom fields
|
||||
%w[
|
||||
create_topic_wizard
|
||||
].each do |custom_field|
|
||||
%w[create_topic_wizard].each do |custom_field|
|
||||
Site.preloaded_category_custom_fields << custom_field
|
||||
end
|
||||
|
||||
Liquid::Template.register_filter(::CustomWizard::LiquidFilter::FirstNonEmpty)
|
||||
|
||||
add_to_class(:topic, :wizard_submission_id) do
|
||||
custom_fields['wizard_submission_id']
|
||||
end
|
||||
add_to_class(:topic, :wizard_submission_id) { custom_fields["wizard_submission_id"] }
|
||||
|
||||
add_class_method(:wizard, :user_requires_completion?) do |user|
|
||||
wizard_result = self.new(user).requires_completion?
|
||||
|
@ -127,10 +121,7 @@ after_initialize do
|
|||
|
||||
custom_redirect = false
|
||||
|
||||
if user &&
|
||||
user.first_seen_at.blank? &&
|
||||
wizard = CustomWizard::Wizard.after_signup(user)
|
||||
|
||||
if user && user.first_seen_at.blank? && wizard = CustomWizard::Wizard.after_signup(user)
|
||||
if !wizard.completed?
|
||||
custom_redirect = true
|
||||
CustomWizard::Wizard.set_user_redirect(wizard.id, user)
|
||||
|
@ -141,8 +132,8 @@ after_initialize do
|
|||
end
|
||||
|
||||
add_to_class(:user, :redirect_to_wizard) do
|
||||
if custom_fields['redirect_to_wizard'].present?
|
||||
custom_fields['redirect_to_wizard']
|
||||
if custom_fields["redirect_to_wizard"].present?
|
||||
custom_fields["redirect_to_wizard"]
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
@ -156,9 +147,7 @@ after_initialize do
|
|||
end
|
||||
end
|
||||
|
||||
add_to_serializer(:current_user, :redirect_to_wizard) do
|
||||
object.redirect_to_wizard
|
||||
end
|
||||
add_to_serializer(:current_user, :redirect_to_wizard) { object.redirect_to_wizard }
|
||||
|
||||
on(:user_approved) do |user|
|
||||
if wizard = CustomWizard::Wizard.after_signup(user)
|
||||
|
@ -167,16 +156,16 @@ after_initialize do
|
|||
end
|
||||
|
||||
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
|
||||
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
|
||||
wizard_id = current_user.redirect_to_wizard
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
|
@ -209,9 +198,10 @@ after_initialize do
|
|||
::UsersController.prepend CustomWizardUsersController
|
||||
::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)
|
||||
Stylesheet::Importer.plugin_assets['wizard_custom'] = Set[full_path]
|
||||
Stylesheet::Importer.plugin_assets["wizard_custom"] = Set[full_path]
|
||||
else
|
||||
# legacy method, Discourse 2.7.0.beta5 and below
|
||||
DiscoursePluginRegistry.register_asset(full_path, {}, "wizard_custom")
|
||||
|
@ -225,7 +215,9 @@ after_initialize do
|
|||
|
||||
add_model_callback(klass, :after_initialize) do
|
||||
if CustomWizard::CustomField.enabled?
|
||||
CustomWizard::CustomField.list_by(:klass, klass.to_s).each do |field|
|
||||
CustomWizard::CustomField
|
||||
.list_by(:klass, klass.to_s)
|
||||
.each do |field|
|
||||
class_constant.register_custom_field_type(field[:name], field[:type].to_sym)
|
||||
end
|
||||
end
|
||||
|
@ -247,10 +239,10 @@ after_initialize do
|
|||
|
||||
on(:before_create_topic) do |topic_params, user|
|
||||
category = topic_params.category
|
||||
wizard_submission_id = topic_params.custom_fields&.[]('wizard_submission_id')
|
||||
if category&.custom_fields&.[]('create_topic_wizard').present? && wizard_submission_id.blank?
|
||||
wizard_submission_id = topic_params.custom_fields&.[]("wizard_submission_id")
|
||||
if category&.custom_fields&.[]("create_topic_wizard").present? && wizard_submission_id.blank?
|
||||
raise Discourse::InvalidParameters.new(
|
||||
I18n.t('wizard.error_messages.wizard_replacing_composer')
|
||||
I18n.t("wizard.error_messages.wizard_replacing_composer"),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::Action do
|
||||
fab!(:user) { Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com", trust_level: TrustLevel[2]) }
|
||||
fab!(:user1) { Fabricate(:user, name: "Angus One", username: 'angus1', email: "angus_one@email.com", trust_level: TrustLevel[2]) }
|
||||
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') }
|
||||
fab!(:tag) { Fabricate(:tag, name: 'tag1') }
|
||||
fab!(:user) do
|
||||
Fabricate(
|
||||
:user,
|
||||
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)
|
||||
|
||||
let(:wizard_template) { get_wizard_fixture("wizard") }
|
||||
|
@ -24,103 +40,94 @@ describe CustomWizard::Action do
|
|||
|
||||
def update_template(template)
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
@template = CustomWizard::Template.find('super_mega_fun_wizard')
|
||||
@template = CustomWizard::Template.find("super_mega_fun_wizard")
|
||||
end
|
||||
|
||||
let(:create_topic) {
|
||||
let(:create_topic) do
|
||||
JSON.parse(
|
||||
File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/create_topic.json"
|
||||
).read
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/create_topic.json",
|
||||
).read,
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:custom_field_json) {
|
||||
JSON.parse(File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
|
||||
).read)
|
||||
}
|
||||
let(:custom_field_json) do
|
||||
JSON.parse(
|
||||
File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json",
|
||||
).read,
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
Group.refresh_automatic_group!(:trust_level_2)
|
||||
update_template(wizard_template)
|
||||
end
|
||||
|
||||
describe '#create_topic' do
|
||||
describe "#create_topic" do
|
||||
it "works" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_1: "Topic Title",
|
||||
step_1_field_2: "topic body"
|
||||
step_1_field_2: "topic body",
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id,
|
||||
step_3_field_3: category.id
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.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(Post.where(
|
||||
topic_id: topic.pluck(:id),
|
||||
raw: "topic body"
|
||||
).exists?).to eq(true)
|
||||
expect(Post.where(topic_id: topic.pluck(:id), raw: "topic body").exists?).to eq(true)
|
||||
end
|
||||
|
||||
it "fails silently without basic topic inputs" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_2: "topic body"
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.first.id, step_1_field_2: "topic body").update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
updater = wizard.create_updater(wizard.steps.last.id, {})
|
||||
updater.update
|
||||
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(CustomWizard::UserHistory.where(
|
||||
expect(
|
||||
CustomWizard::UserHistory.where(
|
||||
actor_id: user.id,
|
||||
context: "super_mega_fun_wizard",
|
||||
subject: "step_3"
|
||||
).exists?).to eq(true)
|
||||
expect(Post.where(
|
||||
raw: "topic body"
|
||||
).exists?).to eq(false)
|
||||
subject: "step_3",
|
||||
).exists?,
|
||||
).to eq(true)
|
||||
expect(Post.where(raw: "topic body").exists?).to eq(false)
|
||||
end
|
||||
|
||||
it "adds custom fields" do
|
||||
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_2: "topic body"
|
||||
step_1_field_2: "topic body",
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id,
|
||||
step_3_field_3: category.id
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
|
||||
|
||||
topic = Topic.where(
|
||||
title: "Topic Title",
|
||||
category_id: category.id
|
||||
).first
|
||||
topic_custom_field = TopicCustomField.where(
|
||||
topic = Topic.where(title: "Topic Title", category_id: category.id).first
|
||||
topic_custom_field =
|
||||
TopicCustomField.where(
|
||||
name: "topic_field",
|
||||
value: "Topic custom field value",
|
||||
topic_id: topic.id
|
||||
topic_id: topic.id,
|
||||
)
|
||||
topic_json_custom_field = TopicCustomField.where("
|
||||
topic_json_custom_field =
|
||||
TopicCustomField.where(
|
||||
"
|
||||
name = 'topic_json_field' AND
|
||||
(value::json->>'key_1') = 'Key 1 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 =
|
||||
PostCustomField.where(
|
||||
name: "post_field",
|
||||
value: "Post custom field value",
|
||||
post_id: topic.first_post.id
|
||||
post_id: topic.first_post.id,
|
||||
)
|
||||
expect(topic_custom_field.exists?).to eq(true)
|
||||
expect(topic_json_custom_field.exists?).to eq(true)
|
||||
|
@ -128,32 +135,33 @@ describe CustomWizard::Action do
|
|||
end
|
||||
|
||||
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_value = "Custom value"
|
||||
|
||||
CustomWizard::CustomField.new(nil, custom_field).save
|
||||
create_topic["custom_fields"] = [
|
||||
{
|
||||
"type": "association",
|
||||
"pairs": [
|
||||
type: "association",
|
||||
pairs: [
|
||||
{
|
||||
"index": 0,
|
||||
"key": custom_field_name,
|
||||
"key_type": "custom_field",
|
||||
"value": custom_field_value,
|
||||
"value_type": "text",
|
||||
"connector": "association"
|
||||
}
|
||||
]
|
||||
}
|
||||
index: 0,
|
||||
key: custom_field_name,
|
||||
key_type: "custom_field",
|
||||
value: custom_field_value,
|
||||
value_type: "text",
|
||||
connector: "association",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
wizard = CustomWizard::Wizard.new(@template, user)
|
||||
action = CustomWizard::Action.new(
|
||||
action =
|
||||
CustomWizard::Action.new(
|
||||
wizard: wizard,
|
||||
action: create_topic.with_indifferent_access,
|
||||
submission: wizard.current_submission
|
||||
submission: wizard.current_submission,
|
||||
)
|
||||
action.perform
|
||||
|
||||
|
@ -163,14 +171,7 @@ describe CustomWizard::Action do
|
|||
|
||||
it "allows poster to be set" do
|
||||
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)
|
||||
|
||||
|
@ -178,45 +179,39 @@ describe CustomWizard::Action do
|
|||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_1: "Topic Title",
|
||||
step_1_field_2: "topic body"
|
||||
step_1_field_2: "topic body",
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id,
|
||||
step_3_field_3: category.id
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.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)
|
||||
post = Post.find_by(
|
||||
topic_id: topic.pluck(:id),
|
||||
raw: "topic body"
|
||||
)
|
||||
post = Post.find_by(topic_id: topic.pluck(:id), raw: "topic body")
|
||||
expect(post.present?).to eq(true)
|
||||
expect(post.user.username).to eq('angus1')
|
||||
expect(post.user.username).to eq("angus1")
|
||||
end
|
||||
end
|
||||
|
||||
it 'updates a profile' do
|
||||
it "updates a profile" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
upload = Upload.create!(
|
||||
url: '/images/image.png',
|
||||
original_filename: 'image.png',
|
||||
upload =
|
||||
Upload.create!(
|
||||
url: "/images/image.png",
|
||||
original_filename: "image.png",
|
||||
filesize: 100,
|
||||
user_id: -1,
|
||||
)
|
||||
steps = wizard.steps
|
||||
wizard.create_updater(steps[0].id, {}).update
|
||||
wizard.create_updater(steps[1].id,
|
||||
step_2_field_7: upload.as_json(only: [:id, :url, :user_id])
|
||||
wizard.create_updater(
|
||||
steps[1].id,
|
||||
step_2_field_7: upload.as_json(only: %i[id url user_id]),
|
||||
).update
|
||||
expect(user.profile_background_upload.id).to eq(upload.id)
|
||||
end
|
||||
|
||||
context "open composer" do
|
||||
it 'works' do
|
||||
it "works" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
|
||||
|
||||
|
@ -224,19 +219,20 @@ describe CustomWizard::Action do
|
|||
updater.update
|
||||
|
||||
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
|
||||
|
||||
it 'encodes special characters in the title and body' do
|
||||
open_composer['title'][0]['output'] = "Title that's special $".dup
|
||||
open_composer['post_template'] = "Body & more body & more body".dup
|
||||
it "encodes special characters in the title and body" do
|
||||
open_composer["title"][0]["output"] = "Title that's special $".dup
|
||||
open_composer["post_template"] = "Body & more body & more body".dup
|
||||
|
||||
wizard = CustomWizard::Wizard.new(@template, user)
|
||||
action = CustomWizard::Action.new(
|
||||
action =
|
||||
CustomWizard::Action.new(
|
||||
wizard: wizard,
|
||||
action: open_composer,
|
||||
submission: wizard.current_submission
|
||||
submission: wizard.current_submission,
|
||||
)
|
||||
action.perform
|
||||
|
||||
|
@ -244,13 +240,13 @@ describe CustomWizard::Action do
|
|||
|
||||
decoded_output = CGI.parse(URI.parse(action.result.output).query)
|
||||
|
||||
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["title"][0]).to eq("Title that's special $")
|
||||
expect(decoded_output["body"][0]).to eq("Body & more body & more body")
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
updater = wizard.create_updater(wizard.steps.last.id, {})
|
||||
updater.update
|
||||
|
@ -274,7 +270,7 @@ describe CustomWizard::Action do
|
|||
Jobs.run_immediately!
|
||||
end
|
||||
|
||||
it 'watches tags' do
|
||||
it "watches tags" do
|
||||
watch_tags[:tags][0][:output] = tag.name
|
||||
wizard_template[:actions] << watch_tags
|
||||
update_template(wizard_template)
|
||||
|
@ -282,13 +278,10 @@ describe CustomWizard::Action do
|
|||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
|
||||
|
||||
expect(TagUser.where(
|
||||
tag_id: tag.id,
|
||||
user_id: user.id
|
||||
).first.notification_level).to eq(2)
|
||||
expect(TagUser.where(tag_id: tag.id, user_id: user.id).first.notification_level).to eq(2)
|
||||
end
|
||||
|
||||
it 'watches categories' do
|
||||
it "watches categories" do
|
||||
watch_categories[:categories][0][:output] = category.id
|
||||
wizard_template[:actions] << watch_categories
|
||||
update_template(wizard_template)
|
||||
|
@ -296,34 +289,27 @@ describe CustomWizard::Action do
|
|||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
|
||||
|
||||
expect(CategoryUser.where(
|
||||
category_id: category.id,
|
||||
user_id: user.id
|
||||
).first.notification_level).to eq(2)
|
||||
expect(
|
||||
CategoryUser.where(category_id: category.id, user_id: user.id).first.notification_level,
|
||||
).to eq(2)
|
||||
end
|
||||
|
||||
it '#send_message' do
|
||||
it "#send_message" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
target_user = Fabricate(:user)
|
||||
|
||||
send_message['recipient'][0]['output'][0] = target_user.username
|
||||
wizard_template['actions'] << send_message
|
||||
send_message["recipient"][0]["output"][0] = target_user.username
|
||||
wizard_template["actions"] << send_message
|
||||
update_template(wizard_template)
|
||||
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(wizard.steps[0].id, {}).update
|
||||
wizard.create_updater(wizard.steps[1].id, {}).update
|
||||
|
||||
topic = Topic.where(
|
||||
archetype: Archetype.private_message,
|
||||
title: "Message title"
|
||||
)
|
||||
topic = Topic.where(archetype: Archetype.private_message, title: "Message title")
|
||||
|
||||
post = Post.where(
|
||||
topic_id: topic.pluck(:id),
|
||||
raw: "I will interpolate some wizard fields"
|
||||
)
|
||||
post = Post.where(topic_id: topic.pluck(:id), raw: "I will interpolate some wizard fields")
|
||||
|
||||
expect(topic.exists?).to eq(true)
|
||||
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)
|
||||
end
|
||||
|
||||
it '#send_message allows using multiple targets' do
|
||||
it "#send_message allows using multiple targets" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
user1 = Fabricate(:user)
|
||||
|
@ -339,13 +325,13 @@ describe CustomWizard::Action do
|
|||
group1 = Fabricate(:group)
|
||||
group2 = Fabricate(:group)
|
||||
|
||||
send_message_multi['recipient'][0]['output'] = [
|
||||
send_message_multi["recipient"][0]["output"] = [
|
||||
user1.username,
|
||||
user2.username,
|
||||
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)
|
||||
|
||||
|
@ -353,18 +339,15 @@ describe CustomWizard::Action do
|
|||
wizard.create_updater(wizard.steps[0].id, {}).update
|
||||
wizard.create_updater(wizard.steps[1].id, {}).update
|
||||
|
||||
topic = Topic.where(
|
||||
archetype: Archetype.private_message,
|
||||
title: "Multiple Recipients title"
|
||||
)
|
||||
topic = Topic.where(archetype: Archetype.private_message, title: "Multiple Recipients title")
|
||||
|
||||
post = Post.where(
|
||||
topic_id: topic.pluck(:id),
|
||||
raw: "I will interpolate some wizard fields"
|
||||
)
|
||||
post = Post.where(topic_id: topic.pluck(:id), raw: "I will interpolate some wizard fields")
|
||||
|
||||
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(post.exists?).to eq(true)
|
||||
expect(user1.reload.notifications.count).to eq(1)
|
||||
|
@ -378,27 +361,27 @@ describe CustomWizard::Action do
|
|||
|
||||
wizard_template["permitted"] = guests_permitted["permitted"]
|
||||
wizard_template[:steps][0][:fields] << {
|
||||
"id": "step_1_field_5",
|
||||
"label": "Guest Email",
|
||||
"type": "text",
|
||||
"min_length": "3",
|
||||
id: "step_1_field_5",
|
||||
label: "Guest Email",
|
||||
type: "text",
|
||||
min_length: "3",
|
||||
}.as_json
|
||||
create_topic["run_after"] = "step_3"
|
||||
create_topic["guest_email"] = [
|
||||
{
|
||||
"type": "assignment",
|
||||
"output": "step_1_field_5",
|
||||
"output_type": "wizard_field",
|
||||
"output_connector": "set"
|
||||
}
|
||||
type: "assignment",
|
||||
output: "step_1_field_5",
|
||||
output_type: "wizard_field",
|
||||
output_connector: "set",
|
||||
},
|
||||
]
|
||||
create_topic["category"] = [
|
||||
{
|
||||
"type": "assignment",
|
||||
"output": "step_3_field_3",
|
||||
"output_type": "wizard_field",
|
||||
"output_connector": "set"
|
||||
}
|
||||
type: "assignment",
|
||||
output: "step_3_field_3",
|
||||
output_type: "wizard_field",
|
||||
output_connector: "set",
|
||||
},
|
||||
]
|
||||
wizard_template.delete("actions")
|
||||
wizard_template[:actions] = [create_topic]
|
||||
|
@ -407,47 +390,39 @@ describe CustomWizard::Action do
|
|||
end
|
||||
|
||||
it "creates a staged guest poster if guest_email is set" do
|
||||
wizard = CustomWizard::Builder.new(
|
||||
wizard =
|
||||
CustomWizard::Builder.new(
|
||||
@template[:id],
|
||||
nil,
|
||||
CustomWizard::Wizard.generate_guest_id
|
||||
CustomWizard::Wizard.generate_guest_id,
|
||||
).build
|
||||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_5: "guest@email.com"
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.first.id, step_1_field_5: "guest@email.com").update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id,
|
||||
step_3_field_3: category.id
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
|
||||
|
||||
topic = Topic.where(category_id: category.id).first
|
||||
expect(topic.present?).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
|
||||
|
||||
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 =
|
||||
CustomWizard::Builder.new(
|
||||
@template[:id],
|
||||
nil,
|
||||
CustomWizard::Wizard.generate_guest_id
|
||||
CustomWizard::Wizard.generate_guest_id,
|
||||
).build
|
||||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_5: "guest@email.com"
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.first.id, step_1_field_5: "guest@email.com").update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id,
|
||||
step_3_field_3: category.id
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
|
||||
|
||||
topic = Topic.where(category_id: category.id).first
|
||||
expect(topic.present?).to eq(true)
|
||||
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
|
||||
|
||||
|
@ -455,10 +430,15 @@ describe CustomWizard::Action do
|
|||
it "works" do
|
||||
wizard_template["permitted"] = guests_permitted["permitted"]
|
||||
wizard_template.delete("actions")
|
||||
wizard_template['actions'] = [send_message]
|
||||
wizard_template["actions"] = [send_message]
|
||||
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
|
||||
updater = wizard.create_updater(wizard.steps[1].id, {})
|
||||
updater.update
|
||||
|
@ -468,7 +448,9 @@ describe CustomWizard::Action do
|
|||
|
||||
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.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)
|
||||
end
|
||||
|
||||
|
@ -480,19 +462,24 @@ describe CustomWizard::Action do
|
|||
|
||||
send_message["recipient"] = [
|
||||
{
|
||||
"type": "assignment",
|
||||
"output": "step_1_field_1",
|
||||
"output_type": "wizard_field",
|
||||
"output_connector": "set"
|
||||
}
|
||||
type: "assignment",
|
||||
output: "step_1_field_1",
|
||||
output_type: "wizard_field",
|
||||
output_connector: "set",
|
||||
},
|
||||
]
|
||||
|
||||
wizard_template['actions'] = [send_message]
|
||||
wizard_template["actions"] = [send_message]
|
||||
update_template(wizard_template)
|
||||
|
||||
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
|
||||
updater = wizard.create_updater(wizard.steps[1].id, {})
|
||||
updater.update
|
||||
|
@ -502,8 +489,12 @@ describe CustomWizard::Action do
|
|||
|
||||
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.primary_email.email).to eq('guest@email.com')
|
||||
expect(topic.first.topic_allowed_users.second.user.username).to eq(Discourse.system_user.username)
|
||||
expect(topic.first.topic_allowed_users.first.user.primary_email.email).to eq(
|
||||
"guest@email.com",
|
||||
)
|
||||
expect(topic.first.topic_allowed_users.second.user.username).to eq(
|
||||
Discourse.system_user.username,
|
||||
)
|
||||
expect(post.exists?).to eq(true)
|
||||
end
|
||||
end
|
||||
|
@ -511,71 +502,71 @@ describe CustomWizard::Action do
|
|||
end
|
||||
|
||||
context "business subscription actions" do
|
||||
before do
|
||||
enable_subscription("business")
|
||||
end
|
||||
before { enable_subscription("business") }
|
||||
|
||||
it '#create_category' do
|
||||
wizard_template['actions'] << create_category
|
||||
wizard_template['actions'] << create_group
|
||||
it "#create_category" do
|
||||
wizard_template["actions"] << create_category
|
||||
wizard_template["actions"] << create_group
|
||||
update_template(wizard_template)
|
||||
|
||||
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[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
|
||||
|
||||
it '#create_group' do
|
||||
wizard_template['actions'] << create_group
|
||||
it "#create_group" do
|
||||
wizard_template["actions"] << create_group
|
||||
update_template(wizard_template)
|
||||
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
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
|
||||
user_id = User.find_by(username: wizard_template['actions'][4]['usernames'][0]["output"][0]).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
|
||||
|
||||
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)
|
||||
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
|
||||
wizard_template['actions'] << create_group_with_nonexistent_user
|
||||
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
|
||||
update_template(wizard_template)
|
||||
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
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(Group.where(name: wizard.current_submission.fields['action_9']).exists?).to eq(true)
|
||||
expect(
|
||||
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)
|
||||
end
|
||||
|
||||
it '#add_to_group' do
|
||||
wizard_template['actions'] << create_group
|
||||
wizard_template['actions'] << add_to_group
|
||||
it "#add_to_group" do
|
||||
wizard_template["actions"] << create_group
|
||||
wizard_template["actions"] << add_to_group
|
||||
update_template(wizard_template)
|
||||
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
step_id = wizard.steps[0].id
|
||||
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
|
||||
|
||||
it '#send_to_api successful' do
|
||||
stub_request(:put, "https://myexternalapi.com/update").
|
||||
with(
|
||||
it "#send_to_api successful" do
|
||||
stub_request(:put, "https://myexternalapi.com/update").with(
|
||||
body: "some_body",
|
||||
headers: {
|
||||
'Host' => 'myexternalapi.com'
|
||||
}).
|
||||
to_return(status: 200, body: "success", headers: {})
|
||||
"Host" => "myexternalapi.com",
|
||||
},
|
||||
).to_return(status: 200, body: "success", headers: {})
|
||||
|
||||
new_api = CustomWizard::Api.new("my_api")
|
||||
CustomWizard::Api.set("my_api", title: "Mocked external api")
|
||||
|
@ -587,18 +578,17 @@ describe CustomWizard::Action do
|
|||
result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body")
|
||||
log_entry = CustomWizard::Api::LogEntry.list("my_api").first
|
||||
|
||||
expect(result).to eq('success')
|
||||
expect(log_entry.status).to eq('SUCCESS')
|
||||
expect(result).to eq("success")
|
||||
expect(log_entry.status).to eq("SUCCESS")
|
||||
end
|
||||
|
||||
it '#send_to_api failure' do
|
||||
stub_request(:put, "https://myexternalapi.com/update").
|
||||
with(
|
||||
it "#send_to_api failure" do
|
||||
stub_request(:put, "https://myexternalapi.com/update").with(
|
||||
body: "some_body",
|
||||
headers: {
|
||||
'Host' => 'myexternalapi.com'
|
||||
}).
|
||||
to_return(status: 500, body: "failure", headers: {})
|
||||
"Host" => "myexternalapi.com",
|
||||
},
|
||||
).to_return(status: 500, body: "failure", headers: {})
|
||||
|
||||
new_api = CustomWizard::Api.new("my_api")
|
||||
CustomWizard::Api.set("my_api", title: "Mocked external api")
|
||||
|
@ -611,21 +601,22 @@ describe CustomWizard::Action do
|
|||
log_entry = CustomWizard::Api::LogEntry.list("my_api").first
|
||||
|
||||
expect(result).to eq({ error: "API request failed" })
|
||||
expect(log_entry.status).to eq('FAIL')
|
||||
expect(log_entry.status).to eq("FAIL")
|
||||
end
|
||||
end
|
||||
|
||||
it 'registers callbacks' do
|
||||
it "registers callbacks" do
|
||||
described_class.register_callback(:before_create_topic) do |params, wizard, action, submission|
|
||||
params[:topic_opts][:custom_fields]["topic_custom_field"] = true
|
||||
params
|
||||
end
|
||||
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
action = CustomWizard::Action.new(
|
||||
action =
|
||||
CustomWizard::Action.new(
|
||||
wizard: wizard,
|
||||
action: create_topic.with_indifferent_access,
|
||||
submission: wizard.current_submission
|
||||
submission: wizard.current_submission,
|
||||
)
|
||||
action.perform
|
||||
|
||||
|
@ -633,27 +624,24 @@ describe CustomWizard::Action do
|
|||
expect(Topic.find(action.result.output).custom_fields["topic_custom_field"]).to eq("t")
|
||||
end
|
||||
|
||||
context 'creating a topic when there are multiple actions' do
|
||||
it 'works' do
|
||||
wizard_template['actions'] << create_topic
|
||||
wizard_template['actions'] << send_message
|
||||
context "creating a topic when there are multiple actions" do
|
||||
it "works" do
|
||||
wizard_template["actions"] << create_topic
|
||||
wizard_template["actions"] << send_message
|
||||
update_template(wizard_template)
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_1: 'Topic Title',
|
||||
step_1_field_2: 'topic body'
|
||||
step_1_field_1: "Topic Title",
|
||||
step_1_field_2: "topic body",
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id)
|
||||
.update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
|
||||
wizard.create_updater(wizard.steps[0].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(
|
||||
Post.where(topic_id: topic.pluck(:id), raw: 'topic body').exists?
|
||||
).to eq(true)
|
||||
expect(Post.where(topic_id: topic.pluck(:id), raw: "topic body").exists?).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::Builder do
|
||||
fab!(:trusted_user) {
|
||||
Fabricate(
|
||||
:user,
|
||||
username: 'angus',
|
||||
email: "angus@email.com",
|
||||
trust_level: TrustLevel[3]
|
||||
)
|
||||
}
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:category1) { Fabricate(:category, name: 'cat1') }
|
||||
fab!(:category2) { Fabricate(:category, name: 'cat2') }
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
fab!(:trusted_user) do
|
||||
Fabricate(:user, username: "angus", email: "angus@email.com", trust_level: TrustLevel[3])
|
||||
end
|
||||
fab!(:user)
|
||||
fab!(:category1) { Fabricate(:category, name: "cat1") }
|
||||
fab!(:category2) { Fabricate(:category, name: "cat2") }
|
||||
fab!(:group)
|
||||
|
||||
let(:wizard_template) { get_wizard_fixture("wizard") }
|
||||
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(:user_condition_json) { get_wizard_fixture("condition/user_condition") }
|
||||
|
||||
let(:boolean_field_condition_json) {
|
||||
let(:boolean_field_condition_json) do
|
||||
JSON.parse(
|
||||
File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/boolean_field_condition.json"
|
||||
).read
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/boolean_field_condition.json",
|
||||
).read,
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
Group.refresh_automatic_group!(:trust_level_3)
|
||||
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
|
||||
|
||||
context 'disabled' do
|
||||
before do
|
||||
SiteSetting.custom_wizard_enabled = false
|
||||
end
|
||||
context "disabled" do
|
||||
before { SiteSetting.custom_wizard_enabled = false }
|
||||
|
||||
it "returns nil" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
).to eq(nil)
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'enabled' do
|
||||
before do
|
||||
SiteSetting.custom_wizard_enabled = true
|
||||
end
|
||||
context "enabled" do
|
||||
before { SiteSetting.custom_wizard_enabled = true }
|
||||
|
||||
it "returns wizard metadata" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
|
@ -59,10 +48,7 @@ describe CustomWizard::Builder do
|
|||
end
|
||||
|
||||
it "returns steps" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.length
|
||||
).to eq(3)
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(3)
|
||||
end
|
||||
|
||||
context "with multiple submissions disabled" do
|
||||
|
@ -71,27 +57,21 @@ describe CustomWizard::Builder do
|
|||
CustomWizard::Template.save(@template.as_json)
|
||||
end
|
||||
|
||||
it 'returns steps if user has not completed it' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.length
|
||||
).to eq(3)
|
||||
it "returns steps if user has not completed it" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(3)
|
||||
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|
|
||||
CustomWizard::UserHistory.create!(
|
||||
action: CustomWizard::UserHistory.actions[:step],
|
||||
actor_id: user.id,
|
||||
context: @template[:id],
|
||||
subject: step[:id]
|
||||
subject: step[:id],
|
||||
)
|
||||
end
|
||||
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.length
|
||||
).to eq(0)
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -102,81 +82,56 @@ describe CustomWizard::Builder do
|
|||
CustomWizard::Template.save(@template.as_json)
|
||||
end
|
||||
|
||||
it 'is not permitted if user is not in permitted group' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.permitted?
|
||||
).to eq(false)
|
||||
it "is not permitted if user is not in permitted group" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.permitted?).to eq(false)
|
||||
end
|
||||
|
||||
it 'user cannot access if not permitted' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.can_access?
|
||||
).to eq(false)
|
||||
it "user cannot access if not permitted" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.can_access?).to eq(false)
|
||||
end
|
||||
|
||||
it 'returns wizard metadata if user is not permitted' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.name
|
||||
).to eq("Super Mega Fun Wizard")
|
||||
it "returns wizard metadata if user is not permitted" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.name).to eq(
|
||||
"Super Mega Fun Wizard",
|
||||
)
|
||||
end
|
||||
|
||||
it 'returns no steps if user is not permitted' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.length
|
||||
).to eq(0)
|
||||
it "returns no steps if user is not permitted" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.steps.length).to eq(0)
|
||||
end
|
||||
|
||||
it 'is permitted if user is in permitted group' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], trusted_user).build
|
||||
.permitted?
|
||||
).to eq(true)
|
||||
it "is permitted if user is in permitted group" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], trusted_user).build.permitted?).to eq(true)
|
||||
end
|
||||
|
||||
it 'user can access if permitted' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], trusted_user).build
|
||||
.can_access?
|
||||
).to eq(true)
|
||||
it "user can access if permitted" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], trusted_user).build.can_access?).to eq(
|
||||
true,
|
||||
)
|
||||
end
|
||||
|
||||
it 'returns steps if user is permitted' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], trusted_user).build
|
||||
.steps.length
|
||||
).to eq(3)
|
||||
it "returns steps if user is permitted" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], trusted_user).build.steps.length).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns prefilled data' do
|
||||
it "returns prefilled data" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.first
|
||||
.fields.first
|
||||
.value
|
||||
).to eq('I am prefilled')
|
||||
CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.first.value,
|
||||
).to eq("I am prefilled")
|
||||
end
|
||||
|
||||
context "user has partially completed" do
|
||||
before do
|
||||
wizard = CustomWizard::Wizard.new(@template, user)
|
||||
data = {
|
||||
step_1_field_1: 'I am a user submission'
|
||||
}
|
||||
data = { step_1_field_1: "I am a user submission" }
|
||||
CustomWizard::Submission.new(wizard, data).save
|
||||
end
|
||||
|
||||
it 'returns saved submissions' do
|
||||
it "returns saved submissions" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.first
|
||||
.fields.first
|
||||
.value
|
||||
).to eq('I am a user submission')
|
||||
CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.first.value,
|
||||
).to eq("I am a user submission")
|
||||
end
|
||||
|
||||
context "restart is enabled" do
|
||||
|
@ -186,100 +141,87 @@ describe CustomWizard::Builder do
|
|||
CustomWizard::Template.save(@template.as_json)
|
||||
end
|
||||
|
||||
it 'does not return saved submissions' do
|
||||
it "does not return saved submissions" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.first
|
||||
.fields.first
|
||||
.value
|
||||
).to eq('I am prefilled')
|
||||
CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.first.value,
|
||||
).to eq("I am prefilled")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'building step' do
|
||||
it 'returns step metadata' do
|
||||
first_step = CustomWizard::Builder.new(@template[:id], user)
|
||||
.build(reset: true)
|
||||
.steps.first
|
||||
context "building step" do
|
||||
it "returns step metadata" do
|
||||
first_step = CustomWizard::Builder.new(@template[:id], user).build(reset: true).steps.first
|
||||
|
||||
expect(first_step.id).to eq("step_1")
|
||||
expect(first_step.title).to eq("Text")
|
||||
expect(first_step.description).to eq("<p>Text inputs!</p>")
|
||||
end
|
||||
|
||||
context 'with required data' do
|
||||
context "with required data" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
@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] = required_data_json["required_data"]
|
||||
@template[:steps][0][:required_data_message] = required_data_json["required_data_message"]
|
||||
CustomWizard::Template.save(@template.as_json)
|
||||
end
|
||||
|
||||
it 'is not permitted if required data is not present' do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.first
|
||||
.permitted
|
||||
).to eq(false)
|
||||
it "is not permitted if required data is not present" do
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.steps.first.permitted).to eq(
|
||||
false,
|
||||
)
|
||||
end
|
||||
|
||||
it 'it shows required data message' do
|
||||
it "it shows required data message" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.first
|
||||
.permitted_message
|
||||
CustomWizard::Builder.new(@template[:id], user).build.steps.first.permitted_message,
|
||||
).to eq("Missing required data")
|
||||
end
|
||||
|
||||
it 'is permitted if required data is present' do
|
||||
wizard = CustomWizard::Wizard.create('super_mega_fun_wizard', user)
|
||||
it "is permitted if required data is present" do
|
||||
wizard = CustomWizard::Wizard.create("super_mega_fun_wizard", user)
|
||||
CustomWizard::Submission.new(wizard, step_1_field_1: "required").save
|
||||
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user).build
|
||||
.steps.first
|
||||
.permitted
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Builder.new(@template[:id], user).build.steps.first.permitted).to eq(
|
||||
true,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "with permitted params" do
|
||||
before do
|
||||
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)
|
||||
end
|
||||
|
||||
it 'saves permitted params' do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build({},
|
||||
param: 'param_value'
|
||||
)
|
||||
expect(wizard.current_submission.fields['saved_param']).to eq('param_value')
|
||||
it "saves permitted params" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build({}, param: "param_value")
|
||||
expect(wizard.current_submission.fields["saved_param"]).to eq("param_value")
|
||||
end
|
||||
end
|
||||
|
||||
context "with condition" do
|
||||
before do
|
||||
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)
|
||||
end
|
||||
|
||||
it "adds step when condition is passed" do
|
||||
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
|
||||
|
||||
it "does not add step when condition is not passed" do
|
||||
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
|
||||
|
||||
context 'building field' do
|
||||
it 'returns field metadata' do
|
||||
context "building field" do
|
||||
it "returns field metadata" do
|
||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
field = wizard.steps.first.fields.first
|
||||
|
||||
|
@ -289,59 +231,56 @@ describe CustomWizard::Builder do
|
|||
expect(field.min_length).to eq("3")
|
||||
end
|
||||
|
||||
it 'returns all step fields' do
|
||||
it "returns all step fields" do
|
||||
expect(
|
||||
CustomWizard::Builder.new(@template[:id], user)
|
||||
.build
|
||||
.steps.first
|
||||
.fields.length
|
||||
CustomWizard::Builder.new(@template[:id], user).build.steps.first.fields.length,
|
||||
).to eq(@template[:steps][0][:fields].length)
|
||||
end
|
||||
|
||||
context "with condition" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
|
||||
@template[:steps][2][:fields][0][:condition] = boolean_field_condition_json['condition']
|
||||
@template[:steps][0][:fields][0][:condition] = user_condition_json["condition"]
|
||||
@template[:steps][2][:fields][0][:condition] = boolean_field_condition_json["condition"]
|
||||
CustomWizard::Template.save(@template.as_json)
|
||||
end
|
||||
|
||||
it "adds field when condition is passed" do
|
||||
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
|
||||
|
||||
it "does not add field when condition is not passed" do
|
||||
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
|
||||
|
||||
it "works if a field condition uses 'is true/false'" do
|
||||
builder = CustomWizard::Builder.new(@template[:id], user)
|
||||
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)
|
||||
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
|
||||
|
||||
context 'on update' do
|
||||
context "on update" do
|
||||
def perform_update(step_id, submission)
|
||||
updater = @wizard.create_updater(step_id, submission)
|
||||
updater.update
|
||||
updater
|
||||
end
|
||||
|
||||
it 'saves submissions' do
|
||||
it "saves submissions" do
|
||||
@wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||
perform_update('step_1', step_1_field_1: 'Text input')
|
||||
expect(@wizard.current_submission.fields['step_1_field_1']).to eq('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")
|
||||
end
|
||||
|
||||
context 'save submissions disabled' do
|
||||
context "save submissions disabled" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
@template[:save_submissions] = false
|
||||
|
@ -350,7 +289,7 @@ describe CustomWizard::Builder do
|
|||
end
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,22 +2,20 @@
|
|||
|
||||
describe CustomWizard::Cache do
|
||||
it "writes and reads values to the cache" do
|
||||
CustomWizard::Cache.new('list').write([1, 2, 3])
|
||||
expect(CustomWizard::Cache.new('list').read).to eq([1, 2, 3])
|
||||
CustomWizard::Cache.new("list").write([1, 2, 3])
|
||||
expect(CustomWizard::Cache.new("list").read).to eq([1, 2, 3])
|
||||
end
|
||||
|
||||
it "deletes values from the cache" do
|
||||
CustomWizard::Cache.new('list').delete
|
||||
expect(CustomWizard::Cache.new('list').read).to eq(nil)
|
||||
CustomWizard::Cache.new("list").delete
|
||||
expect(CustomWizard::Cache.new("list").read).to eq(nil)
|
||||
end
|
||||
|
||||
describe "#wrap" do
|
||||
before do
|
||||
@raw = [1, 2, 3]
|
||||
end
|
||||
before { @raw = [1, 2, 3] }
|
||||
|
||||
def list
|
||||
CustomWizard::Cache.wrap('list') { @raw }
|
||||
CustomWizard::Cache.wrap("list") { @raw }
|
||||
end
|
||||
|
||||
it "returns value from passed block" do
|
||||
|
|
|
@ -2,224 +2,229 @@
|
|||
|
||||
describe CustomWizard::CustomField do
|
||||
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
|
||||
let(:custom_field_subscription_json) { get_wizard_fixture("custom_field/subscription_custom_fields") }
|
||||
|
||||
before do
|
||||
CustomWizard::CustomField.invalidate_cache
|
||||
let(:custom_field_subscription_json) do
|
||||
get_wizard_fixture("custom_field/subscription_custom_fields")
|
||||
end
|
||||
|
||||
before { CustomWizard::CustomField.invalidate_cache }
|
||||
|
||||
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)
|
||||
expect(custom_field.save).to eq(true)
|
||||
expect(
|
||||
PluginStoreRow.where("
|
||||
PluginStoreRow.where(
|
||||
"
|
||||
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
|
||||
key = '#{custom_field.name}' AND
|
||||
value::jsonb = '#{field_json.except('name').to_json}'::jsonb
|
||||
",).exists?
|
||||
value::jsonb = '#{field_json.except("name").to_json}'::jsonb
|
||||
",
|
||||
).exists?,
|
||||
).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
updated_field_json = custom_field_json['custom_fields'][0]
|
||||
updated_field_json['serializers'] = ["topic_view"]
|
||||
updated_field_json = custom_field_json["custom_fields"][0]
|
||||
updated_field_json["serializers"] = ["topic_view"]
|
||||
existing_field = CustomWizard::CustomField.find_by_name(updated_field_json["name"])
|
||||
updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json)
|
||||
|
||||
expect(updated_field.save).to eq(true)
|
||||
expect(
|
||||
PluginStoreRow.where("
|
||||
PluginStoreRow.where(
|
||||
"
|
||||
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
|
||||
key = '#{updated_field.name}' AND
|
||||
value::jsonb = '#{updated_field_json.except('name').to_json}'::jsonb
|
||||
",).exists?
|
||||
value::jsonb = '#{updated_field_json.except("name").to_json}'::jsonb
|
||||
",
|
||||
).exists?,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
context "validation" do
|
||||
it "does not save without required attributes" do
|
||||
invalid_field_json = custom_field_json['custom_fields'].first
|
||||
invalid_field_json['klass'] = nil
|
||||
invalid_field_json = custom_field_json["custom_fields"].first
|
||||
invalid_field_json["klass"] = nil
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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(
|
||||
PluginStoreRow.where(
|
||||
plugin_name: CustomWizard::CustomField::NAMESPACE,
|
||||
key: custom_field.name
|
||||
).exists?
|
||||
key: custom_field.name,
|
||||
).exists?,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "does save without optional attributes" do
|
||||
field_json = custom_field_json['custom_fields'].first
|
||||
field_json['serializers'] = nil
|
||||
field_json = custom_field_json["custom_fields"].first
|
||||
field_json["serializers"] = nil
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, field_json)
|
||||
expect(custom_field.save).to eq(true)
|
||||
expect(custom_field.valid?).to eq(true)
|
||||
expect(
|
||||
PluginStoreRow.where("
|
||||
PluginStoreRow.where(
|
||||
"
|
||||
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
|
||||
key = '#{custom_field.name}' AND
|
||||
value::jsonb = '#{field_json.except('name').to_json}'::jsonb
|
||||
",).exists?
|
||||
value::jsonb = '#{field_json.except("name").to_json}'::jsonb
|
||||
",
|
||||
).exists?,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "does not save with an unsupported class" do
|
||||
invalid_field_json = custom_field_json['custom_fields'].first
|
||||
invalid_field_json['klass'] = 'user'
|
||||
invalid_field_json = custom_field_json["custom_fields"].first
|
||||
invalid_field_json["klass"] = "user"
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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(
|
||||
PluginStoreRow.where(
|
||||
plugin_name: CustomWizard::CustomField::NAMESPACE,
|
||||
key: custom_field.name
|
||||
).exists?
|
||||
key: custom_field.name,
|
||||
).exists?,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "does not save with an unsupported serializer" do
|
||||
invalid_field_json = custom_field_json['custom_fields'].first
|
||||
invalid_field_json['klass'] = 'post'
|
||||
invalid_field_json['serializers'] = ['post', 'post_revision']
|
||||
invalid_field_json = custom_field_json["custom_fields"].first
|
||||
invalid_field_json["klass"] = "post"
|
||||
invalid_field_json["serializers"] = %w[post post_revision]
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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",
|
||||
serializers: "post_revision"
|
||||
)
|
||||
serializers: "post_revision",
|
||||
),
|
||||
)
|
||||
expect(
|
||||
PluginStoreRow.where(
|
||||
plugin_name: CustomWizard::CustomField::NAMESPACE,
|
||||
key: custom_field.name
|
||||
).exists?
|
||||
key: custom_field.name,
|
||||
).exists?,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "does not save with an unsupported type" do
|
||||
invalid_field_json = custom_field_json['custom_fields'].first
|
||||
invalid_field_json['type'] = 'bigint'
|
||||
invalid_field_json = custom_field_json["custom_fields"].first
|
||||
invalid_field_json["type"] = "bigint"
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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(
|
||||
PluginStoreRow.where(
|
||||
plugin_name: CustomWizard::CustomField::NAMESPACE,
|
||||
key: custom_field.name
|
||||
).exists?
|
||||
key: custom_field.name,
|
||||
).exists?,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "does not save with a short field name" do
|
||||
invalid_field_json = custom_field_json['custom_fields'].first
|
||||
invalid_field_json['name'] = 'cf'
|
||||
invalid_field_json = custom_field_json["custom_fields"].first
|
||||
invalid_field_json["name"] = "cf"
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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(
|
||||
PluginStoreRow.where(
|
||||
plugin_name: CustomWizard::CustomField::NAMESPACE,
|
||||
key: custom_field.name
|
||||
).exists?
|
||||
key: custom_field.name,
|
||||
).exists?,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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
|
||||
|
||||
it "does not save with an invalid name" do
|
||||
invalid_field_json = custom_field_json['custom_fields'].first
|
||||
invalid_field_json['name'] = ["invalid_name"]
|
||||
invalid_field_json = custom_field_json["custom_fields"].first
|
||||
invalid_field_json["name"] = ["invalid_name"]
|
||||
|
||||
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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(
|
||||
PluginStoreRow.where(
|
||||
plugin_name: CustomWizard::CustomField::NAMESPACE,
|
||||
key: custom_field.name
|
||||
).exists?
|
||||
key: custom_field.name,
|
||||
).exists?,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
expect(custom_field.save).to eq(false)
|
||||
expect(custom_field.valid?).to eq(false)
|
||||
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
|
||||
|
||||
context "with a subscription" do
|
||||
before do
|
||||
enable_subscription("business")
|
||||
end
|
||||
before { enable_subscription("business") }
|
||||
|
||||
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)
|
||||
|
||||
expect(custom_field.save).to eq(true)
|
||||
|
@ -227,7 +232,7 @@ describe CustomWizard::CustomField do
|
|||
end
|
||||
|
||||
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)
|
||||
|
||||
expect(custom_field.save).to eq(true)
|
||||
|
@ -238,7 +243,7 @@ describe CustomWizard::CustomField do
|
|||
|
||||
context "lists" 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
|
||||
end
|
||||
end
|
||||
|
@ -248,15 +253,15 @@ describe CustomWizard::CustomField do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
it "saved custom field records by optional values" do
|
||||
field_json = custom_field_json['custom_fields'].first
|
||||
field_json['serializers'] = nil
|
||||
field_json = custom_field_json["custom_fields"].first
|
||||
field_json["serializers"] = nil
|
||||
|
||||
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
|
||||
|
||||
it "custom field records added by other plugins " do
|
||||
|
@ -269,7 +274,7 @@ describe CustomWizard::CustomField do
|
|||
end
|
||||
|
||||
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
|
||||
end
|
||||
expect(CustomWizard::CustomField.enabled?).to eq(true)
|
||||
|
|
|
@ -5,12 +5,14 @@ describe CustomWizard::Field do
|
|||
|
||||
before do
|
||||
CustomWizard::Field.register(
|
||||
'location',
|
||||
'discourse-locations',
|
||||
['components', 'helpers', 'lib', 'stylesheets', 'templates'],
|
||||
"location",
|
||||
"discourse-locations",
|
||||
%w[components helpers lib stylesheets templates],
|
||||
type_opts: {
|
||||
prefill: { "coordinates": [35.3082, 149.1244] }
|
||||
}
|
||||
prefill: {
|
||||
coordinates: [35.3082, 149.1244],
|
||||
},
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -31,14 +33,14 @@ describe CustomWizard::Field do
|
|||
end
|
||||
|
||||
it "allows custom field types to set default attributes" do
|
||||
expect(
|
||||
CustomWizard::Field.types[:location][:prefill]
|
||||
).to eq({ "coordinates": [35.3082, 149.1244] })
|
||||
expect(CustomWizard::Field.types[:location][:prefill]).to eq(
|
||||
{ coordinates: [35.3082, 149.1244] },
|
||||
)
|
||||
end
|
||||
|
||||
it "registers custom field assets" do
|
||||
expect(
|
||||
CustomWizard::Field.require_assets['discourse-locations']
|
||||
).to eq(['components', 'helpers', 'lib', 'stylesheets', 'templates'])
|
||||
expect(CustomWizard::Field.require_assets["discourse-locations"]).to eq(
|
||||
%w[components helpers lib stylesheets templates],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,32 +2,42 @@
|
|||
|
||||
describe CustomWizard::Log do
|
||||
before do
|
||||
CustomWizard::Log.create('first-test-wizard', '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)
|
||||
CustomWizard::Log.create(
|
||||
"first-test-wizard",
|
||||
"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
|
||||
|
||||
it "creates logs" do
|
||||
expect(
|
||||
CustomWizard::Log.list.logs.length
|
||||
).to eq(3)
|
||||
expect(CustomWizard::Log.list.logs.length).to eq(3)
|
||||
end
|
||||
|
||||
it "lists logs by time created" do
|
||||
expect(
|
||||
CustomWizard::Log.list.logs.first.message
|
||||
).to eq("Third log message")
|
||||
expect(CustomWizard::Log.list.logs.first.message).to eq("Third log message")
|
||||
end
|
||||
|
||||
it "paginates logs" do
|
||||
expect(
|
||||
CustomWizard::Log.list(0, 2).logs.length
|
||||
).to eq(2)
|
||||
expect(CustomWizard::Log.list(0, 2).logs.length).to eq(2)
|
||||
end
|
||||
|
||||
it "lists logs by wizard" do
|
||||
expect(
|
||||
CustomWizard::Log.list(0, 2, 'third-test-wizard').logs.length
|
||||
).to eq(1)
|
||||
expect(CustomWizard::Log.list(0, 2, "third-test-wizard").logs.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,429 +1,403 @@
|
|||
# rubocop:disable Style/FrozenStringLiteralComment
|
||||
|
||||
describe CustomWizard::Mapper do
|
||||
fab!(:user1) {
|
||||
Fabricate(:user,
|
||||
fab!(:user1) do
|
||||
Fabricate(
|
||||
:user,
|
||||
name: "Angus",
|
||||
username: "angus",
|
||||
email: "angus@email.com",
|
||||
trust_level: TrustLevel[3]
|
||||
trust_level: TrustLevel[3],
|
||||
)
|
||||
}
|
||||
fab!(:user2) {
|
||||
Fabricate(:user,
|
||||
end
|
||||
fab!(:user2) do
|
||||
Fabricate(
|
||||
:user,
|
||||
name: "Patrick",
|
||||
username: "patrick",
|
||||
email: "patrick@email2.com",
|
||||
trust_level: TrustLevel[1]
|
||||
trust_level: TrustLevel[1],
|
||||
)
|
||||
}
|
||||
fab!(:user_field) {
|
||||
field = Fabricate(:user_field,
|
||||
end
|
||||
fab!(:user_field) do
|
||||
field =
|
||||
Fabricate(
|
||||
:user_field,
|
||||
id: 3,
|
||||
name: 'dropdown_field',
|
||||
description: 'field desc',
|
||||
field_type: 'dropdown',
|
||||
user_field_options_attributes: [
|
||||
{ value: "a" },
|
||||
{ value: "b" },
|
||||
{ value: "c" }
|
||||
]
|
||||
name: "dropdown_field",
|
||||
description: "field desc",
|
||||
field_type: "dropdown",
|
||||
user_field_options_attributes: [{ value: "a" }, { value: "b" }, { value: "c" }],
|
||||
)
|
||||
}
|
||||
end
|
||||
let(:inputs) { get_wizard_fixture("mapper/inputs") }
|
||||
let(:data) { get_wizard_fixture("mapper/data") }
|
||||
let(:template_params) {
|
||||
{
|
||||
"step_1_field_1" => "Hello"
|
||||
}
|
||||
}
|
||||
let(:template_params_empty) {
|
||||
{
|
||||
"step_1_field_1" => nil,
|
||||
"step_1_field_2" => nil,
|
||||
"step_1_field_3" => ""
|
||||
}
|
||||
}
|
||||
let(:template_params_non_empty) {
|
||||
{
|
||||
"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" }]
|
||||
}
|
||||
}
|
||||
let(:template_params) { { "step_1_field_1" => "Hello" } }
|
||||
let(:template_params_empty) do
|
||||
{ "step_1_field_1" => nil, "step_1_field_2" => nil, "step_1_field_3" => "" }
|
||||
end
|
||||
let(:template_params_non_empty) do
|
||||
{ "step_1_field_1" => nil, "step_1_field_2" => "", "step_1_field_3" => "Value" }
|
||||
end
|
||||
let(:template_params_multiple_non_empty) do
|
||||
{ "step_1_field_1" => nil, "step_1_field_2" => "Value1", "step_1_field_3" => "Value" }
|
||||
end
|
||||
let(:template_params_object) { { step_1_field_1: get_wizard_fixture("field/upload") } }
|
||||
let(:template_params_object_array) do
|
||||
{ "step_1_field_1" => [{ text: "Hello" }, { text: "World" }] }
|
||||
end
|
||||
|
||||
def create_template_mapper(data, user)
|
||||
CustomWizard::Mapper.new(
|
||||
data: data,
|
||||
user: user
|
||||
)
|
||||
CustomWizard::Mapper.new(data: data, user: user)
|
||||
end
|
||||
|
||||
it "maps values" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['assignment'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq([13])
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["assignment"], data: data, user: user1).perform,
|
||||
).to eq([13])
|
||||
end
|
||||
|
||||
it "maps associations" do
|
||||
association = CustomWizard::Mapper.new(
|
||||
inputs: inputs['association'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform
|
||||
association =
|
||||
CustomWizard::Mapper.new(inputs: inputs["association"], data: data, user: user1).perform
|
||||
expect(association.length).to eq(3)
|
||||
expect(association.first[:value]).to eq("Choice 1")
|
||||
end
|
||||
|
||||
context "conditional mapping" do
|
||||
it "maps when the condition is met" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['conditional'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("true")
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["conditional"], data: data, user: user1).perform,
|
||||
).to eq("true")
|
||||
end
|
||||
|
||||
it "does not map when the condition is not met" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['conditional'],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(nil)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["conditional"], data: data, user: user2).perform,
|
||||
).to eq(nil)
|
||||
end
|
||||
|
||||
it "maps when multiple conditions are met" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['conditional_multiple_pairs'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["conditional_multiple_pairs"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("true")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("true")
|
||||
end
|
||||
|
||||
it "does not map when one of multiple conditions are not met" do
|
||||
user1.email = "angus@other-email.com"
|
||||
user1.save
|
||||
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['conditional_multiple_pairs'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["conditional_multiple_pairs"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(nil)
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "conditional validation" do
|
||||
it "validates valid data" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['validation'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["validation"], data: data, user: user1).perform,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "does not validate invalid data" do
|
||||
data["input_2"] = "value 3"
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['validation'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(false)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["validation"], data: data, user: user1).perform,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
context "using or condition" do
|
||||
it "validates the data when all of the conditions are met" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['validation_multiple_pairs'],
|
||||
expect(
|
||||
CustomWizard::Mapper
|
||||
.new(
|
||||
inputs: inputs["validation_multiple_pairs"],
|
||||
data: data,
|
||||
user: user1,
|
||||
opts: {
|
||||
multiple: true
|
||||
}
|
||||
).perform.any?).to eq(true)
|
||||
multiple: true,
|
||||
},
|
||||
)
|
||||
.perform
|
||||
.any?,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "validates the data when one of the conditions are met" do
|
||||
custom_data = data.dup
|
||||
custom_data['input_1'] = 'value 3'
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['validation_multiple_pairs'],
|
||||
custom_data["input_1"] = "value 3"
|
||||
expect(
|
||||
CustomWizard::Mapper
|
||||
.new(
|
||||
inputs: inputs["validation_multiple_pairs"],
|
||||
data: custom_data,
|
||||
user: user1,
|
||||
opts: {
|
||||
multiple: true
|
||||
}
|
||||
).perform.any?).to eq(true)
|
||||
multiple: true,
|
||||
},
|
||||
)
|
||||
.perform
|
||||
.any?,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "doesn't validate the data when none of the conditions are met" do
|
||||
custom_data = data.dup
|
||||
custom_data['input_1'] = 'value 3'
|
||||
custom_data['input_2'] = 'value 4'
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['validation_multiple_pairs'],
|
||||
custom_data["input_1"] = "value 3"
|
||||
custom_data["input_2"] = "value 4"
|
||||
expect(
|
||||
CustomWizard::Mapper
|
||||
.new(
|
||||
inputs: inputs["validation_multiple_pairs"],
|
||||
data: custom_data,
|
||||
user: user1,
|
||||
opts: {
|
||||
multiple: true
|
||||
}
|
||||
).perform.any?).to eq(false)
|
||||
multiple: true,
|
||||
},
|
||||
)
|
||||
.perform
|
||||
.any?,
|
||||
).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "maps text fields" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['assignment_text'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Value")
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["assignment_text"], data: data, user: user1).perform,
|
||||
).to eq("Value")
|
||||
end
|
||||
|
||||
it "maps user fields" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['assignment_user_field'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["assignment_user_field"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Angus")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("Angus")
|
||||
end
|
||||
|
||||
it "maps user field options" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['assignment_user_field_options'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["assignment_user_field_options"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(["a", "b", "c"])
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq(%w[a b c])
|
||||
end
|
||||
|
||||
it "maps wizard fields" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['assignment_wizard_field'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["assignment_wizard_field"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("value 1")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("value 1")
|
||||
end
|
||||
|
||||
it "maps wizard actions" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['assignment_wizard_action'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["assignment_wizard_action"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("value 2")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("value 2")
|
||||
end
|
||||
|
||||
context "interpolates" do
|
||||
it "user fields" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['interpolate_user_field'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["interpolate_user_field"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Name: Angus")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("Name: Angus")
|
||||
end
|
||||
|
||||
it "user emails" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['interpolate_user_email'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["interpolate_user_email"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Email: angus@email.com")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("Email: angus@email.com")
|
||||
end
|
||||
|
||||
it "user options" do
|
||||
user1.user_option.update_columns(email_level: UserOption.email_level_types[:never])
|
||||
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['interpolate_user_option'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["interpolate_user_option"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Email Level: #{UserOption.email_level_types[:never]}")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("Email Level: #{UserOption.email_level_types[:never]}")
|
||||
end
|
||||
|
||||
it "date" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['interpolate_timestamp'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["interpolate_timestamp"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}")
|
||||
end
|
||||
|
||||
it "avatar" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['interpolate_avatar'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["interpolate_avatar"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
|
||||
end
|
||||
|
||||
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})"
|
||||
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: avatar_inputs,
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: avatar_inputs, data: data, user: user1).perform,
|
||||
).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
|
||||
end
|
||||
|
||||
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})"
|
||||
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: avatar_inputs,
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq("Avatar: ![avatar](#{user1.avatar_template_url.gsub("{size}", "144")})")
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: avatar_inputs, data: data, user: user1).perform,
|
||||
).to eq("Avatar: ![avatar](#{user1.avatar_template_url.gsub("{size}", "144")})")
|
||||
end
|
||||
end
|
||||
|
||||
it "handles not equal pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['not_equals_pair'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(true)
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['not_equals_pair'],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(false)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["not_equals_pair"], data: data, user: user1).perform,
|
||||
).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["not_equals_pair"], data: data, user: user2).perform,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "handles greater than pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['greater_than_pair'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["greater_than_pair"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(true)
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['greater_than_pair'],
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["greater_than_pair"],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(false)
|
||||
user: user2,
|
||||
).perform,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "handles less than pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['less_than_pair'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(false)
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['less_than_pair'],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["less_than_pair"], data: data, user: user1).perform,
|
||||
).to eq(false)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["less_than_pair"], data: data, user: user2).perform,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "handles greater than or equal pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['greater_than_or_equal_pair'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["greater_than_or_equal_pair"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(true)
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['greater_than_or_equal_pair'],
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["greater_than_or_equal_pair"],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(true)
|
||||
user: user2,
|
||||
).perform,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "handles less than or equal pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['less_than_or_equal_pair'],
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["less_than_or_equal_pair"],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(true)
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['less_than_or_equal_pair'],
|
||||
user: user1,
|
||||
).perform,
|
||||
).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: inputs["less_than_or_equal_pair"],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(true)
|
||||
user: user2,
|
||||
).perform,
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "handles regex pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['regex_pair'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(true)
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['regex_pair'],
|
||||
data: data,
|
||||
user: user2
|
||||
).perform).to eq(false)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["regex_pair"], data: data, user: user1).perform,
|
||||
).to eq(true)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["regex_pair"], data: data, user: user2).perform,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
it "handles shorthand pairs" do
|
||||
expect(CustomWizard::Mapper.new(
|
||||
inputs: inputs['shorthand_pair'],
|
||||
data: data,
|
||||
user: user1
|
||||
).perform).to eq(false)
|
||||
expect(
|
||||
CustomWizard::Mapper.new(inputs: inputs["shorthand_pair"], data: data, user: user1).perform,
|
||||
).to eq(false)
|
||||
end
|
||||
|
||||
context "output templating" do
|
||||
it "passes the correct values to the template" do
|
||||
template = "w{step_1_field_1}"
|
||||
mapper = create_template_mapper(template_params, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq(template_params["step_1_field_1"])
|
||||
end
|
||||
|
||||
it "does not require a subscription" do
|
||||
template = '{{ "w{step_1_field_1}" | size }}'
|
||||
mapper = create_template_mapper(template_params, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq("5")
|
||||
end
|
||||
|
||||
context "with a subscription" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
end
|
||||
before { enable_subscription("standard") }
|
||||
|
||||
it "treats replaced values as string literals" do
|
||||
template = '{{ "w{step_1_field_1}" | size }}'
|
||||
mapper = create_template_mapper(template_params, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq(template_params["step_1_field_1"].size.to_s)
|
||||
end
|
||||
|
||||
|
@ -436,26 +410,16 @@ describe CustomWizard::Mapper do
|
|||
{%-endif-%}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq("Correct")
|
||||
end
|
||||
|
||||
it "can access data passed to render method as variable" do
|
||||
template = "{{step_1_field_1.size}}"
|
||||
mapper = create_template_mapper(template_params, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq(template_params["step_1_field_1"].size.to_s)
|
||||
end
|
||||
|
||||
|
@ -464,10 +428,7 @@ describe CustomWizard::Mapper do
|
|||
{{ "w{step_1_field_1}" | size}}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: false,
|
||||
)
|
||||
result = mapper.interpolate(template.dup, template: false)
|
||||
expect(result).to eq(template)
|
||||
end
|
||||
|
||||
|
@ -480,11 +441,7 @@ describe CustomWizard::Mapper do
|
|||
{%-endif-%}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params_object, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
wizard: true
|
||||
)
|
||||
result = mapper.interpolate(template.dup, template: true, wizard: true)
|
||||
expect(result).to eq("Correct")
|
||||
end
|
||||
|
||||
|
@ -497,11 +454,7 @@ describe CustomWizard::Mapper do
|
|||
{%-endif-%}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params_object, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
wizard: true
|
||||
)
|
||||
result = mapper.interpolate(template.dup, template: true, wizard: true)
|
||||
expect(result).to eq("Incorrect")
|
||||
end
|
||||
|
||||
|
@ -510,13 +463,8 @@ describe CustomWizard::Mapper do
|
|||
{% for object in step_1_field_1 %}{{object.text}} {% endfor %}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params_object_array, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq("Hello World ")
|
||||
end
|
||||
|
||||
|
@ -527,13 +475,8 @@ describe CustomWizard::Mapper do
|
|||
{{ entry }}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params_non_empty, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq(template_params_non_empty["step_1_field_3"])
|
||||
end
|
||||
|
||||
|
@ -543,13 +486,8 @@ describe CustomWizard::Mapper do
|
|||
{{ entry }}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params_multiple_non_empty, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq(template_params_multiple_non_empty["step_1_field_2"])
|
||||
end
|
||||
|
||||
|
@ -561,13 +499,8 @@ describe CustomWizard::Mapper do
|
|||
{%- endif -%}
|
||||
LIQUID
|
||||
mapper = create_template_mapper(template_params_empty, user1)
|
||||
result = mapper.interpolate(
|
||||
template.dup,
|
||||
template: true,
|
||||
user: true,
|
||||
wizard: true,
|
||||
value: true
|
||||
)
|
||||
result =
|
||||
mapper.interpolate(template.dup, template: true, user: true, wizard: true, value: true)
|
||||
expect(result).to eq("")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,9 @@ describe ::CustomWizard::RealtimeValidation::SimilarTopics do
|
|||
let(:topic) { post.topic }
|
||||
|
||||
let(:category) { Fabricate(:category) }
|
||||
let(:cat_post) { create_post(title: "matching similar topic slightly different", category: category) }
|
||||
let(:cat_post) do
|
||||
create_post(title: "matching similar topic slightly different", category: category)
|
||||
end
|
||||
let(:cat_topic) { cat_post.topic }
|
||||
let(:user) { cat_post.user }
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@ describe CustomWizard::Step do
|
|||
let(:step_hash) { get_wizard_fixture("step/step") }
|
||||
let(:field_hash) { get_wizard_fixture("field/field") }
|
||||
|
||||
before do
|
||||
@step = CustomWizard::Step.new(step_hash[:id])
|
||||
end
|
||||
before { @step = CustomWizard::Step.new(step_hash[:id]) }
|
||||
|
||||
it "adds fields" do
|
||||
@step.add_field(field_hash)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::Submission do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
let(:template_json) { get_wizard_fixture("wizard") }
|
||||
let(:guest_id) { CustomWizard::Wizard.generate_guest_id }
|
||||
|
@ -13,9 +13,7 @@ describe CustomWizard::Submission do
|
|||
end
|
||||
|
||||
it "saves a user's submission" do
|
||||
expect(
|
||||
described_class.get(@wizard).fields["step_1_field_1"]
|
||||
).to eq("I am user submission")
|
||||
expect(described_class.get(@wizard).fields["step_1_field_1"]).to eq("I am user submission")
|
||||
end
|
||||
|
||||
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)
|
||||
described_class.new(@wizard, step_1_field_1: "I am guest submission").save
|
||||
|
||||
expect(
|
||||
described_class.get(@wizard).fields["step_1_field_1"]
|
||||
).to eq("I am guest submission")
|
||||
expect(described_class.get(@wizard).fields["step_1_field_1"]).to eq("I am guest submission")
|
||||
end
|
||||
|
||||
describe "#list" do
|
||||
|
@ -41,7 +37,11 @@ describe CustomWizard::Submission do
|
|||
@count = CustomWizard::Submission::PAGE_LIMIT + 20
|
||||
|
||||
@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
|
||||
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
|
||||
|
@ -59,11 +59,15 @@ describe CustomWizard::Submission do
|
|||
|
||||
it "paginates submission lists" do
|
||||
@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
|
||||
|
||||
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
|
||||
|
||||
|
@ -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 third submission").save
|
||||
sub_data = PluginStore.get("#{@wizard.id}_submissions", @wizard.user.id)
|
||||
sub_data.each do |sub|
|
||||
sub['updated_at'] = nil
|
||||
end
|
||||
sub_data.each { |sub| sub["updated_at"] = nil }
|
||||
PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, sub_data)
|
||||
builder = CustomWizard::Builder.new(@wizard.id, @wizard.user)
|
||||
builder.build
|
||||
|
@ -101,7 +103,7 @@ describe CustomWizard::Submission do
|
|||
freeze_time Time.now + 2
|
||||
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[0]['updated_at'] = nil
|
||||
sub_data[0]["updated_at"] = nil
|
||||
PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, sub_data)
|
||||
|
||||
builder = CustomWizard::Builder.new(@wizard.id, @wizard.user)
|
||||
|
|
|
@ -5,19 +5,17 @@ describe CustomWizard::Subscription do
|
|||
let!(:business_product_id) { SecureRandom.hex(8) }
|
||||
let!(:standard_product_id) { SecureRandom.hex(8) }
|
||||
let!(:community_product_id) { SecureRandom.hex(8) }
|
||||
let!(:product_slugs) {
|
||||
let!(:product_slugs) do
|
||||
{
|
||||
"#{business_product_id}" => "business",
|
||||
"#{standard_product_id}" => "standard",
|
||||
"#{community_product_id}" => "community"
|
||||
}
|
||||
"#{community_product_id}" => "community",
|
||||
}
|
||||
end
|
||||
|
||||
context "with subscription client gem mocked out" do
|
||||
context "without a subscription" do
|
||||
before do
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(nil)
|
||||
end
|
||||
before { DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(nil) }
|
||||
|
||||
it "has none type" do
|
||||
expect(described_class.type).to eq(:none)
|
||||
|
@ -33,31 +31,43 @@ describe CustomWizard::Subscription do
|
|||
end
|
||||
|
||||
context "with subscriptions" do
|
||||
|
||||
def get_subscription_result(product_ids)
|
||||
result = DiscourseSubscriptionClient::Subscriptions::Result.new
|
||||
result.supplier = SubscriptionClientSupplier.new(products: product_slugs)
|
||||
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
|
||||
end
|
||||
let!(:business_subscription_result) { get_subscription_result([business_product_id]) }
|
||||
let!(:standard_subscription_result) { get_subscription_result([standard_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
|
||||
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)
|
||||
expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(false)
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
|
||||
community_subscription_result,
|
||||
)
|
||||
expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(
|
||||
false,
|
||||
)
|
||||
end
|
||||
|
||||
context "with a standard subscription" do
|
||||
before do
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(standard_subscription_result)
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
|
||||
standard_subscription_result,
|
||||
)
|
||||
end
|
||||
|
||||
it "detects standard type" do
|
||||
|
@ -65,17 +75,19 @@ describe CustomWizard::Subscription do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
context "with a business subscription" do
|
||||
before do
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(business_subscription_result)
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
|
||||
business_subscription_result,
|
||||
)
|
||||
end
|
||||
|
||||
it "detects business type" do
|
||||
|
@ -83,13 +95,15 @@ describe CustomWizard::Subscription do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
context "with a community subscription" do
|
||||
before do
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(community_subscription_result)
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
|
||||
community_subscription_result,
|
||||
)
|
||||
end
|
||||
|
||||
it "detects community type" do
|
||||
|
@ -97,13 +111,15 @@ describe CustomWizard::Subscription do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
context "with multiple subscriptions" do
|
||||
before do
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(multiple_subscription_result)
|
||||
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(
|
||||
multiple_subscription_result,
|
||||
)
|
||||
end
|
||||
|
||||
it "detects correct type in hierarchy" do
|
||||
|
@ -114,22 +130,16 @@ describe CustomWizard::Subscription do
|
|||
end
|
||||
|
||||
context "with environment variable" do
|
||||
before do
|
||||
ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = "standard"
|
||||
end
|
||||
before { ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = "standard" }
|
||||
|
||||
after do
|
||||
ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = nil
|
||||
end
|
||||
after { ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] = nil }
|
||||
|
||||
it "enables the relevant subscription" do
|
||||
expect(described_class.type).to eq(:standard)
|
||||
end
|
||||
|
||||
context "with a subscription" do
|
||||
before do
|
||||
enable_subscription("business")
|
||||
end
|
||||
before { enable_subscription("business") }
|
||||
|
||||
it "respects the subscription" do
|
||||
expect(described_class.type).to eq(:business)
|
||||
|
|
|
@ -1,152 +1,133 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::Template do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
let(:template_json) { get_wizard_fixture("wizard") }
|
||||
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
|
||||
fab!(:upload) { Fabricate(:upload) }
|
||||
fab!(:upload)
|
||||
|
||||
before do
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
end
|
||||
before { CustomWizard::Template.save(template_json, skip_jobs: true) }
|
||||
|
||||
it "saves wizard templates" do
|
||||
expect(
|
||||
PluginStoreRow.exists?(
|
||||
plugin_name: 'custom_wizard',
|
||||
key: 'super_mega_fun_wizard'
|
||||
)
|
||||
PluginStoreRow.exists?(plugin_name: "custom_wizard", key: "super_mega_fun_wizard"),
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "finds wizard templates" do
|
||||
expect(
|
||||
CustomWizard::Template.find('super_mega_fun_wizard')['id']
|
||||
).to eq('super_mega_fun_wizard')
|
||||
expect(CustomWizard::Template.find("super_mega_fun_wizard")["id"]).to eq(
|
||||
"super_mega_fun_wizard",
|
||||
)
|
||||
end
|
||||
|
||||
it "removes wizard templates" do
|
||||
CustomWizard::Template.remove('super_mega_fun_wizard')
|
||||
expect(
|
||||
CustomWizard::Template.find('super_mega_fun_wizard')
|
||||
).to eq(nil)
|
||||
CustomWizard::Template.remove("super_mega_fun_wizard")
|
||||
expect(CustomWizard::Template.find("super_mega_fun_wizard")).to eq(nil)
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
CustomWizard::Template.remove('super_mega_fun_wizard')
|
||||
expect(user.reload.custom_fields['redirect_to_wizard']).to eq(nil)
|
||||
CustomWizard::Template.remove("super_mega_fun_wizard")
|
||||
expect(user.reload.custom_fields["redirect_to_wizard"]).to eq(nil)
|
||||
end
|
||||
|
||||
it "checks for wizard template existence" do
|
||||
expect(
|
||||
CustomWizard::Template.exists?('super_mega_fun_wizard')
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Template.exists?("super_mega_fun_wizard")).to eq(true)
|
||||
end
|
||||
|
||||
context "upload references" 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_id'] = upload.id
|
||||
template_json["steps"][0]["banner"] = upload.url
|
||||
template_json["steps"][0]["banner_upload_id"] = upload.id
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
wizard_record = CustomWizard::Template.find_record(template_json["id"])
|
||||
expect(
|
||||
UploadReference.exists?(
|
||||
upload_id: upload.id,
|
||||
target_type: "PluginStoreRow",
|
||||
target_id: wizard_record.id
|
||||
)
|
||||
target_id: wizard_record.id,
|
||||
),
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
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_id'] = upload.id
|
||||
template_json["steps"][0]["fields"][0]["image"] = upload.url
|
||||
template_json["steps"][0]["fields"][0]["image_upload_id"] = upload.id
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
wizard_record = CustomWizard::Template.find_record(template_json["id"])
|
||||
expect(
|
||||
UploadReference.exists?(
|
||||
upload_id: upload.id,
|
||||
target_type: "PluginStoreRow",
|
||||
target_id: wizard_record.id
|
||||
)
|
||||
target_id: wizard_record.id,
|
||||
),
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it "are removed if a wizard step banner is removed" do
|
||||
template_json['steps'][0]['banner'] = upload.url
|
||||
template_json['steps'][0]['banner_upload_id'] = upload.id
|
||||
template_json["steps"][0]["banner"] = upload.url
|
||||
template_json["steps"][0]["banner_upload_id"] = upload.id
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
|
||||
template_json['steps'][0]['banner'] = nil
|
||||
template_json['steps'][0]['banner_upload_id'] = nil
|
||||
template_json["steps"][0]["banner"] = nil
|
||||
template_json["steps"][0]["banner_upload_id"] = nil
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
wizard_record = CustomWizard::Template.find_record(template_json["id"])
|
||||
expect(
|
||||
UploadReference.exists?(target_type: "PluginStoreRow")
|
||||
).to eq(false)
|
||||
expect(UploadReference.exists?(target_type: "PluginStoreRow")).to eq(false)
|
||||
end
|
||||
|
||||
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_id'] = upload.id
|
||||
template_json["steps"][0]["fields"][0]["image"] = upload.url
|
||||
template_json["steps"][0]["fields"][0]["image_upload_id"] = upload.id
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
|
||||
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"] = nil
|
||||
template_json["steps"][0]["fields"][0]["image_upload_id"] = nil
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
wizard_record = CustomWizard::Template.find_record(template_json["id"])
|
||||
expect(
|
||||
UploadReference.exists?(target_type: "PluginStoreRow")
|
||||
).to eq(false)
|
||||
expect(UploadReference.exists?(target_type: "PluginStoreRow")).to eq(false)
|
||||
end
|
||||
|
||||
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_id'] = upload.id
|
||||
template_json["steps"][0]["fields"][0]["image"] = upload.url
|
||||
template_json["steps"][0]["fields"][0]["image_upload_id"] = upload.id
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
CustomWizard::Template.remove(template_json["id"])
|
||||
expect(
|
||||
UploadReference.exists?(target_type: "PluginStoreRow")
|
||||
).to eq(false)
|
||||
expect(UploadReference.exists?(target_type: "PluginStoreRow")).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "wizard template list" do
|
||||
before do
|
||||
enable_subscription('standard')
|
||||
enable_subscription("standard")
|
||||
|
||||
template_json_2 = template_json.dup
|
||||
template_json_2["id"] = 'super_mega_fun_wizard_2'
|
||||
template_json_2["permitted"] = permitted_json['permitted']
|
||||
template_json_2["id"] = "super_mega_fun_wizard_2"
|
||||
template_json_2["permitted"] = permitted_json["permitted"]
|
||||
CustomWizard::Template.save(template_json_2, skip_jobs: true)
|
||||
|
||||
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
|
||||
CustomWizard::Template.save(template_json_3, skip_jobs: true)
|
||||
end
|
||||
|
||||
it "works" do
|
||||
expect(
|
||||
CustomWizard::Template.list.length
|
||||
).to eq(3)
|
||||
expect(CustomWizard::Template.list.length).to eq(3)
|
||||
end
|
||||
|
||||
it "can be filtered by wizard settings" do
|
||||
expect(
|
||||
CustomWizard::Template.list(setting: "after_signup").length
|
||||
).to eq(1)
|
||||
expect(CustomWizard::Template.list(setting: "after_signup").length).to eq(1)
|
||||
end
|
||||
|
||||
it "can be ordered" do
|
||||
expect(
|
||||
CustomWizard::Template.list(
|
||||
order: "(value::json ->> 'permitted') IS NOT NULL DESC"
|
||||
).first['id']
|
||||
).to eq('super_mega_fun_wizard_2')
|
||||
CustomWizard::Template.list(order: "(value::json ->> 'permitted') IS NOT NULL DESC").first[
|
||||
"id"
|
||||
],
|
||||
).to eq("super_mega_fun_wizard_2")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -160,15 +141,15 @@ describe CustomWizard::Template do
|
|||
@after_time_template["after_time_scheduled"] = @scheduled_time
|
||||
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
|
||||
CustomWizard::Template.save(@after_time_template)
|
||||
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)
|
||||
@after_time_template['after_time'] = false
|
||||
@after_time_template["after_time"] = false
|
||||
|
||||
expect_not_enqueued_with(job: :set_after_time_wizard) do
|
||||
CustomWizard::Template.save(@after_time_template)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::TemplateValidator do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
let(:template) { get_wizard_fixture("wizard") }
|
||||
let(:create_category) { get_wizard_fixture("actions/create_category") }
|
||||
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(:validation_condition) { get_wizard_fixture("condition/validation_condition") }
|
||||
|
||||
let(:valid_liquid_template) {
|
||||
<<-LIQUID.strip
|
||||
let(:valid_liquid_template) { <<-LIQUID.strip }
|
||||
{%- assign hello = "Topic Form 1" %}
|
||||
LIQUID
|
||||
}
|
||||
|
||||
let(:invalid_liquid_template) {
|
||||
<<-LIQUID.strip
|
||||
let(:invalid_liquid_template) { <<-LIQUID.strip }
|
||||
{%- assign hello = "Topic Form 1" %
|
||||
LIQUID
|
||||
}
|
||||
|
||||
let(:liquid_syntax_error) {
|
||||
let(:liquid_syntax_error) do
|
||||
"Liquid syntax error: Tag '{%' was not properly terminated with regexp: /\\%\\}/"
|
||||
}
|
||||
end
|
||||
|
||||
def expect_validation_success
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
def expect_validation_failure(object_id, message)
|
||||
|
@ -40,23 +34,17 @@ describe CustomWizard::TemplateValidator do
|
|||
end
|
||||
|
||||
it "validates valid templates" do
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
it "invalidates templates without required attributes" do
|
||||
template.delete(:id)
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
|
||||
it "invalidates templates with duplicate ids if creating a new template" do
|
||||
CustomWizard::Template.save(template)
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template, create: true).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template, create: true).perform).to eq(false)
|
||||
end
|
||||
|
||||
it "only allows one after signup wizard at a time" do
|
||||
|
@ -70,7 +58,7 @@ describe CustomWizard::TemplateValidator do
|
|||
validator = CustomWizard::TemplateValidator.new(template)
|
||||
expect(validator.perform).to eq(false)
|
||||
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
|
||||
|
||||
|
@ -86,138 +74,106 @@ describe CustomWizard::TemplateValidator do
|
|||
|
||||
validator = CustomWizard::TemplateValidator.new(template)
|
||||
expect(validator.perform).to eq(false)
|
||||
expect(validator.errors.first.type).to eq(
|
||||
I18n.t("wizard.validation.after_signup_after_time")
|
||||
)
|
||||
expect(validator.errors.first.type).to eq(I18n.t("wizard.validation.after_signup_after_time"))
|
||||
end
|
||||
|
||||
it "validates after time settings" do
|
||||
template[:after_time] = true
|
||||
template[:after_time_scheduled] = (Time.now + 3.hours).iso8601
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
it "invalidates invalid after time settings" do
|
||||
template[:after_time] = true
|
||||
template[:after_time_scheduled] = "not a time"
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
|
||||
context "without subscription" do
|
||||
it "invalidates subscription wizard attributes" do
|
||||
template[:permitted] = permitted_json['permitted']
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
template[:permitted] = permitted_json["permitted"]
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
|
||||
it "invalidates subscription step attributes" do
|
||||
template[:steps][0][:condition] = user_condition['condition']
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
template[:steps][0][:condition] = user_condition["condition"]
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
|
||||
it "invalidates subscription field attributes" do
|
||||
template[:steps][0][:fields][0][:condition] = user_condition['condition']
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
template[:steps][0][:fields][0][:condition] = user_condition["condition"]
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
|
||||
it "invalidates subscription actions" do
|
||||
template[:actions] << create_category
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "with subscription" do
|
||||
before do
|
||||
enable_subscription("business")
|
||||
end
|
||||
before { enable_subscription("business") }
|
||||
|
||||
it "validates wizard attributes" do
|
||||
template[:permitted] = permitted_json['permitted']
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
template[:permitted] = permitted_json["permitted"]
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
it "validates user-only features" do
|
||||
template[:permitted] = guests_permitted['permitted']
|
||||
template[:permitted] = guests_permitted["permitted"]
|
||||
template[:steps][0][:fields] << upload_field
|
||||
validator = CustomWizard::TemplateValidator.new(template)
|
||||
expect(validator.perform).to eq(false)
|
||||
errors = validator.errors.to_a
|
||||
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
|
||||
|
||||
it "validates step attributes" do
|
||||
template[:steps][0][:condition] = user_condition['condition']
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
template[:steps][0][:condition] = user_condition["condition"]
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
it "validates field attributes" do
|
||||
template[:steps][0][:fields][0][:condition] = user_condition['condition']
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
template[:steps][0][:fields][0][:condition] = user_condition["condition"]
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
it "validates actions" do
|
||||
template[:actions] << create_category
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
|
||||
it "validates settings with validation conditions" do
|
||||
template[:permitted] = validation_condition["condition"]
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(true)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "steps" do
|
||||
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
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "fields" do
|
||||
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
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "actions" do
|
||||
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
|
||||
expect(
|
||||
CustomWizard::TemplateValidator.new(template).perform
|
||||
).to eq(false)
|
||||
expect(CustomWizard::TemplateValidator.new(template).perform).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::UpdateValidator do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
let(:template) { get_wizard_fixture("wizard") }
|
||||
let(:url_field) { get_wizard_fixture("field/url") }
|
||||
|
||||
before do
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
@template = CustomWizard::Template.find('super_mega_fun_wizard')
|
||||
@template = CustomWizard::Template.find("super_mega_fun_wizard")
|
||||
end
|
||||
|
||||
def perform_validation(step_id, submission)
|
||||
|
@ -17,7 +17,7 @@ describe CustomWizard::UpdateValidator do
|
|||
updater
|
||||
end
|
||||
|
||||
it 'applies min length to text type fields' do
|
||||
it "applies min length to text type fields" do
|
||||
min_length = 3
|
||||
|
||||
@template[:steps][0][:fields][0][:min_length] = min_length
|
||||
|
@ -25,34 +25,35 @@ describe CustomWizard::UpdateValidator do
|
|||
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_1', step_1_field_1: 'Te')
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_1].first
|
||||
).to eq(I18n.t('wizard.field.too_short', label: 'Text', min: min_length))
|
||||
updater = perform_validation("step_1", step_1_field_1: "Te")
|
||||
expect(updater.errors.messages[:step_1_field_1].first).to eq(
|
||||
I18n.t("wizard.field.too_short", label: "Text", min: min_length),
|
||||
)
|
||||
|
||||
updater = perform_validation('step_1', step_1_field_2: 'Te')
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_2].first
|
||||
).to eq(I18n.t('wizard.field.too_short', label: 'Textarea', min: min_length))
|
||||
updater = perform_validation("step_1", step_1_field_2: "Te")
|
||||
expect(updater.errors.messages[:step_1_field_2].first).to eq(
|
||||
I18n.t("wizard.field.too_short", label: "Textarea", min: min_length),
|
||||
)
|
||||
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
|
||||
|
||||
@template[:steps][0][:fields][0][:max_length] = max_length
|
||||
@template[:steps][0][:fields][1][:max_length] = max_length
|
||||
|
||||
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. "
|
||||
updater = perform_validation('step_1', step_1_field_1: long_string)
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_1].first
|
||||
).to eq(I18n.t('wizard.field.too_long', label: 'Text', max: max_length))
|
||||
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. "
|
||||
updater = perform_validation("step_1", step_1_field_1: long_string)
|
||||
expect(updater.errors.messages[:step_1_field_1].first).to eq(
|
||||
I18n.t("wizard.field.too_long", label: "Text", max: max_length),
|
||||
)
|
||||
|
||||
updater = perform_validation('step_1', step_1_field_2: long_string)
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_2].first
|
||||
).to eq(I18n.t('wizard.field.too_long', label: 'Textarea', max: max_length))
|
||||
updater = perform_validation("step_1", step_1_field_2: long_string)
|
||||
expect(updater.errors.messages[:step_1_field_2].first).to eq(
|
||||
I18n.t("wizard.field.too_long", label: "Textarea", max: max_length),
|
||||
)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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."
|
||||
updater = perform_validation('step_1', step_1_field_1: hundred_chars_string)
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_1].first
|
||||
).to eq(nil)
|
||||
hundred_chars_string =
|
||||
"This is a line, exactly hundred characters long and not more even a single character more than that."
|
||||
updater = perform_validation("step_1", step_1_field_1: hundred_chars_string)
|
||||
expect(updater.errors.messages[:step_1_field_1].first).to eq(nil)
|
||||
|
||||
updater = perform_validation('step_1', step_1_field_2: hundred_chars_string)
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_2].first
|
||||
).to eq(nil)
|
||||
updater = perform_validation("step_1", step_1_field_2: hundred_chars_string)
|
||||
expect(updater.errors.messages[:step_1_field_2].first).to eq(nil)
|
||||
end
|
||||
|
||||
it "applies min length only if the input is non-empty" do
|
||||
|
@ -81,10 +79,8 @@ describe CustomWizard::UpdateValidator do
|
|||
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_1', step_1_field_1: '')
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_1].first
|
||||
).to eq(nil)
|
||||
updater = perform_validation("step_1", step_1_field_1: "")
|
||||
expect(updater.errors.messages[:step_1_field_1].first).to eq(nil)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
CustomWizard::Template.save(@template)
|
||||
updater = perform_validation('step_1', step_1_field_1: "")
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_1].first
|
||||
).to eq(nil)
|
||||
updater = perform_validation("step_1", step_1_field_1: "")
|
||||
expect(updater.errors.messages[:step_1_field_1].first).to eq(nil)
|
||||
end
|
||||
|
||||
it 'standardises boolean entries' do
|
||||
updater = perform_validation('step_2', step_2_field_5: 'false')
|
||||
expect(updater.submission['step_2_field_5']).to eq(false)
|
||||
it "standardises boolean entries" do
|
||||
updater = perform_validation("step_2", step_2_field_5: "false")
|
||||
expect(updater.submission["step_2_field_5"]).to eq(false)
|
||||
end
|
||||
|
||||
it 'requires required fields' do
|
||||
it "requires required fields" do
|
||||
@template[:steps][0][:fields][1][:required] = true
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_1', step_1_field_2: nil)
|
||||
expect(
|
||||
updater.errors.messages[:step_1_field_2].first
|
||||
).to eq(I18n.t('wizard.field.required', label: 'Textarea'))
|
||||
updater = perform_validation("step_1", step_1_field_2: nil)
|
||||
expect(updater.errors.messages[:step_1_field_2].first).to eq(
|
||||
I18n.t("wizard.field.required", label: "Textarea"),
|
||||
)
|
||||
end
|
||||
|
||||
context "subscription fields" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
before { 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
|
||||
|
||||
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
|
||||
|
||||
it 'does not validate url fields with non-url inputs' do
|
||||
it "does not validate url fields with non-url inputs" do
|
||||
template[:steps][0][:fields] << url_field
|
||||
CustomWizard::Template.save(template)
|
||||
updater = perform_validation('step_1', step_2_field_6: 'discourse')
|
||||
expect(
|
||||
updater.errors.messages[:step_2_field_6].first
|
||||
).to eq(I18n.t('wizard.field.not_url', label: 'Url'))
|
||||
updater = perform_validation("step_1", step_2_field_6: "discourse")
|
||||
expect(updater.errors.messages[:step_2_field_6].first).to eq(
|
||||
I18n.t("wizard.field.not_url", label: "Url"),
|
||||
)
|
||||
end
|
||||
|
||||
it 'validates empty url fields' do
|
||||
updater = perform_validation('step_2', step_2_field_6: '')
|
||||
expect(
|
||||
updater.errors.messages[:step_2_field_6].first
|
||||
).to eq(nil)
|
||||
it "validates empty url fields" do
|
||||
updater = perform_validation("step_2", step_2_field_6: "")
|
||||
expect(updater.errors.messages[:step_2_field_6].first).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it 'validates date fields' do
|
||||
it "validates date fields" do
|
||||
@template[:steps][1][:fields][0][:format] = "DD-MM-YYYY"
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_2', step_2_field_1: '13-11-2021')
|
||||
expect(
|
||||
updater.errors.messages[:step_2_field_1].first
|
||||
).to eq(nil)
|
||||
updater = perform_validation("step_2", step_2_field_1: "13-11-2021")
|
||||
expect(updater.errors.messages[:step_2_field_1].first).to eq(nil)
|
||||
end
|
||||
|
||||
it 'doesn\'t validate date field if the format is not respected' do
|
||||
@template[:steps][1][:fields][0][:format] = "MM-DD-YYYY"
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_2', step_2_field_1: '13-11-2021')
|
||||
expect(
|
||||
updater.errors.messages[:step_2_field_1].first
|
||||
).to eq(I18n.t('wizard.field.invalid_date'))
|
||||
updater = perform_validation("step_2", step_2_field_1: "13-11-2021")
|
||||
expect(updater.errors.messages[:step_2_field_1].first).to eq(
|
||||
I18n.t("wizard.field.invalid_date"),
|
||||
)
|
||||
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"
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_2', step_2_field_3: '13-11-2021 09:15:00')
|
||||
expect(
|
||||
updater.errors.messages[:step_2_field_3].first
|
||||
).to eq(nil)
|
||||
updater = perform_validation("step_2", step_2_field_3: "13-11-2021 09:15:00")
|
||||
expect(updater.errors.messages[:step_2_field_3].first).to eq(nil)
|
||||
end
|
||||
|
||||
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"
|
||||
CustomWizard::Template.save(@template)
|
||||
|
||||
updater = perform_validation('step_2', step_2_field_3: '13-11-2021 09:15')
|
||||
expect(
|
||||
updater.errors.messages[:step_2_field_3].first
|
||||
).to eq(I18n.t('wizard.field.invalid_date'))
|
||||
updater = perform_validation("step_2", step_2_field_3: "13-11-2021 09:15")
|
||||
expect(updater.errors.messages[:step_2_field_3].first).to eq(
|
||||
I18n.t("wizard.field.invalid_date"),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,9 +19,7 @@ describe CustomWizard::Wizard do
|
|||
end
|
||||
|
||||
def append_steps
|
||||
template_json['steps'].each do |step_template|
|
||||
@wizard.append_step(step_template['id'])
|
||||
end
|
||||
template_json["steps"].each { |step_template| @wizard.append_step(step_template["id"]) }
|
||||
@wizard.update!
|
||||
end
|
||||
|
||||
|
@ -30,7 +28,7 @@ describe CustomWizard::Wizard do
|
|||
action: CustomWizard::UserHistory.actions[:step],
|
||||
actor_id: actor_id,
|
||||
context: wizard.id,
|
||||
subject: step_id
|
||||
subject: step_id,
|
||||
)
|
||||
@wizard.update!
|
||||
end
|
||||
|
@ -47,13 +45,13 @@ describe CustomWizard::Wizard do
|
|||
end
|
||||
|
||||
it "appends steps with custom indexes" do
|
||||
template_json['steps'][0]['index'] = 2
|
||||
template_json['steps'][1]['index'] = 1
|
||||
template_json['steps'][2]['index'] = 0
|
||||
template_json["steps"][0]["index"] = 2
|
||||
template_json["steps"][1]["index"] = 1
|
||||
template_json["steps"][2]["index"] = 0
|
||||
|
||||
template_json['steps'].each do |step_template|
|
||||
@wizard.append_step(step_template['id']) do |step|
|
||||
step.index = step_template['index'] if step_template['index']
|
||||
template_json["steps"].each do |step_template|
|
||||
@wizard.append_step(step_template["id"]) do |step|
|
||||
step.index = step_template["index"] if step_template["index"]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -71,38 +69,35 @@ describe CustomWizard::Wizard do
|
|||
|
||||
it "determines the user's current step" do
|
||||
append_steps
|
||||
expect(@wizard.start).to eq('step_1')
|
||||
progress_step('step_1')
|
||||
expect(@wizard.start).to eq('step_2')
|
||||
expect(@wizard.start).to eq("step_1")
|
||||
progress_step("step_1")
|
||||
expect(@wizard.start).to eq("step_2")
|
||||
end
|
||||
|
||||
it "determines the user's current step if steps are added" do
|
||||
append_steps
|
||||
progress_step('step_1')
|
||||
progress_step('step_2')
|
||||
progress_step("step_1")
|
||||
progress_step("step_2")
|
||||
progress_step("step_3")
|
||||
|
||||
fourth_step = step_json.dup
|
||||
fourth_step['id'] = "step_4"
|
||||
fourth_step["id"] = "step_4"
|
||||
template = template_json.dup
|
||||
template['steps'] << fourth_step
|
||||
template["steps"] << fourth_step
|
||||
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
|
||||
wizard = CustomWizard::Wizard.new(template, user)
|
||||
template['steps'].each do |step_template|
|
||||
wizard.append_step(step_template['id'])
|
||||
end
|
||||
template["steps"].each { |step_template| wizard.append_step(step_template["id"]) }
|
||||
|
||||
expect(wizard.steps.size).to eq(4)
|
||||
expect(wizard.start).to eq(nil)
|
||||
end
|
||||
|
||||
it "creates a step updater" do
|
||||
expect(
|
||||
@wizard.create_updater('step_1', step_1_field_1: "Text input")
|
||||
.class
|
||||
).to eq(CustomWizard::StepUpdater)
|
||||
expect(@wizard.create_updater("step_1", step_1_field_1: "Text input").class).to eq(
|
||||
CustomWizard::StepUpdater,
|
||||
)
|
||||
end
|
||||
|
||||
it "determines whether a wizard is unfinished" do
|
||||
|
@ -133,8 +128,8 @@ describe CustomWizard::Wizard do
|
|||
progress_step("step_2")
|
||||
progress_step("step_3")
|
||||
|
||||
template_json['after_time'] = true
|
||||
template_json['after_time_scheduled'] = Time.now + 3.hours
|
||||
template_json["after_time"] = true
|
||||
template_json["after_time_scheduled"] = Time.now + 3.hours
|
||||
|
||||
wizard = CustomWizard::Wizard.new(template_json, user)
|
||||
expect(wizard.completed?).to eq(true)
|
||||
|
@ -149,9 +144,9 @@ describe CustomWizard::Wizard do
|
|||
progress_step("step_2")
|
||||
progress_step("step_3")
|
||||
|
||||
template_json['after_time'] = true
|
||||
template_json['multiple_submissions'] = true
|
||||
template_json['after_time_scheduled'] = Time.now + 3.hours
|
||||
template_json["after_time"] = true
|
||||
template_json["multiple_submissions"] = true
|
||||
template_json["after_time_scheduled"] = Time.now + 3.hours
|
||||
|
||||
wizard = CustomWizard::Wizard.new(template_json, user)
|
||||
expect(wizard.completed?).to eq(false)
|
||||
|
@ -159,45 +154,31 @@ describe CustomWizard::Wizard do
|
|||
end
|
||||
|
||||
context "with subscription" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
end
|
||||
before { enable_subscription("standard") }
|
||||
|
||||
it "permits admins" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, admin_user).permitted?
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, admin_user).permitted?).to eq(true)
|
||||
end
|
||||
|
||||
it "permits permitted users" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted?
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted?).to eq(true)
|
||||
end
|
||||
|
||||
it "permits everyone if everyone is permitted" do
|
||||
@permitted_template['permitted'][0]['output'] = Group::AUTO_GROUPS[:everyone]
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, user).permitted?
|
||||
).to eq(true)
|
||||
@permitted_template["permitted"][0]["output"] = Group::AUTO_GROUPS[:everyone]
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, user).permitted?).to eq(true)
|
||||
end
|
||||
|
||||
it "does not permit unpermitted users" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, user).permitted?
|
||||
).to eq(false)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, user).permitted?).to eq(false)
|
||||
end
|
||||
|
||||
it "does not let an unpermitted user access a wizard" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, user).can_access?
|
||||
).to eq(false)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, user).can_access?).to eq(false)
|
||||
end
|
||||
|
||||
it "lets a permitted user access an incomplete wizard" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?).to eq(true)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?).to eq(true)
|
||||
end
|
||||
|
||||
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_3", actor_id: trusted_user.id)
|
||||
|
||||
@permitted_template['multiple_submissions'] = false
|
||||
@permitted_template["multiple_submissions"] = false
|
||||
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
|
||||
).to eq(false)
|
||||
expect(CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?).to eq(false)
|
||||
end
|
||||
|
||||
it "sets wizard redirects if user is permitted" do
|
||||
CustomWizard::Template.save(@permitted_template, skip_jobs: true)
|
||||
CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', trusted_user)
|
||||
expect(
|
||||
trusted_user.custom_fields['redirect_to_wizard']
|
||||
).to eq("super_mega_fun_wizard")
|
||||
CustomWizard::Wizard.set_user_redirect("super_mega_fun_wizard", trusted_user)
|
||||
expect(trusted_user.custom_fields["redirect_to_wizard"]).to eq("super_mega_fun_wizard")
|
||||
end
|
||||
|
||||
it "does not set a wizard redirect if user is not permitted" do
|
||||
CustomWizard::Template.save(@permitted_template, skip_jobs: true)
|
||||
CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', user)
|
||||
expect(
|
||||
trusted_user.custom_fields['redirect_to_wizard']
|
||||
).to eq(nil)
|
||||
CustomWizard::Wizard.set_user_redirect("super_mega_fun_wizard", user)
|
||||
expect(trusted_user.custom_fields["redirect_to_wizard"]).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -249,47 +222,39 @@ describe CustomWizard::Wizard do
|
|||
before do
|
||||
enable_subscription("standard")
|
||||
@wizard.restart_on_revisit = true
|
||||
CustomWizard::Template.save(
|
||||
CustomWizard::WizardSerializer.new(@wizard, root: false).as_json
|
||||
)
|
||||
CustomWizard::Template.save(CustomWizard::WizardSerializer.new(@wizard, root: false).as_json)
|
||||
end
|
||||
|
||||
it "returns to step 1 if option to clear submissions on each visit is set" do
|
||||
append_steps
|
||||
expect(@wizard.unfinished?).to eq(true)
|
||||
progress_step('step_1')
|
||||
expect(@wizard.start).to eq('step_1')
|
||||
progress_step("step_1")
|
||||
expect(@wizard.start).to eq("step_1")
|
||||
end
|
||||
end
|
||||
|
||||
context "with subscription and guest wizard" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
end
|
||||
before { enable_subscription("standard") }
|
||||
|
||||
it "permits admins" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@guests_permitted_template, admin_user).permitted?
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Wizard.new(@guests_permitted_template, admin_user).permitted?).to eq(
|
||||
true,
|
||||
)
|
||||
end
|
||||
|
||||
it "permits regular users" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@guests_permitted_template, user).permitted?
|
||||
).to eq(true)
|
||||
expect(CustomWizard::Wizard.new(@guests_permitted_template, user).permitted?).to eq(true)
|
||||
end
|
||||
|
||||
it "permits guests" do
|
||||
expect(
|
||||
CustomWizard::Wizard.new(@guests_permitted_template, nil, "guest123").permitted?
|
||||
CustomWizard::Wizard.new(@guests_permitted_template, nil, "guest123").permitted?,
|
||||
).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "submissions" do
|
||||
before do
|
||||
CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission").save
|
||||
end
|
||||
before { CustomWizard::Submission.new(@wizard, step_1_field_1: "I am a user submission").save }
|
||||
|
||||
it "lists the user's submissions" do
|
||||
expect(@wizard.submissions.length).to eq(1)
|
||||
|
@ -306,12 +271,12 @@ describe CustomWizard::Wizard do
|
|||
CustomWizard::Template.save(@permitted_template, skip_jobs: true)
|
||||
|
||||
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
|
||||
CustomWizard::Template.save(template_json_2, skip_jobs: true)
|
||||
|
||||
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["prompt_completion"] = true
|
||||
CustomWizard::Template.save(template_json_3, skip_jobs: true)
|
||||
|
@ -323,7 +288,7 @@ describe CustomWizard::Wizard do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
it "lists prompt completion wizards" do
|
||||
|
@ -331,7 +296,8 @@ describe CustomWizard::Wizard do
|
|||
end
|
||||
|
||||
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_2", wizard: wizard_2)
|
||||
progress_step("step_3", wizard: wizard_2)
|
||||
|
|
|
@ -5,12 +5,12 @@ describe DiscoursePluginStatistics::Plugin do
|
|||
|
||||
describe "#discourse_custom_wizard" do
|
||||
before do
|
||||
enable_subscription('standard')
|
||||
enable_subscription("standard")
|
||||
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
|
||||
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)
|
||||
|
||||
@data = DiscoursePluginStatistics::Plugin.discourse_custom_wizard
|
||||
|
@ -21,7 +21,7 @@ describe DiscoursePluginStatistics::Plugin do
|
|||
end
|
||||
|
||||
it "includes the subscription type" do
|
||||
expect(@data[:subscription_type]).to eq('standard')
|
||||
expect(@data[:subscription_type]).to eq("standard")
|
||||
end
|
||||
|
||||
it "includes a count of features being used across all wizards" do
|
||||
|
@ -36,7 +36,7 @@ describe DiscoursePluginStatistics::Plugin do
|
|||
step: {
|
||||
required_data: 0,
|
||||
permitted_params: 0,
|
||||
force_final: 0
|
||||
force_final: 0,
|
||||
},
|
||||
field: {
|
||||
condition: 0,
|
||||
|
@ -60,7 +60,7 @@ describe DiscoursePluginStatistics::Plugin do
|
|||
topic: 0,
|
||||
user_selector: 0,
|
||||
},
|
||||
realtime_validations: 0
|
||||
realtime_validations: 0,
|
||||
},
|
||||
action: {
|
||||
type: {
|
||||
|
@ -75,8 +75,8 @@ describe DiscoursePluginStatistics::Plugin do
|
|||
add_to_group: 0,
|
||||
create_group: 0,
|
||||
create_category: 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "custom field extensions" do
|
||||
fab!(:topic) { Fabricate(:topic) }
|
||||
fab!(:post) { Fabricate(:post) }
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:topic)
|
||||
fab!(:post)
|
||||
fab!(:category)
|
||||
fab!(:group)
|
||||
fab!(:user)
|
||||
|
||||
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
|
||||
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.save
|
||||
end
|
||||
|
@ -27,10 +29,11 @@ describe "custom field extensions" do
|
|||
topic.custom_fields["topic_field_1"] = true
|
||||
topic.save_custom_fields(true)
|
||||
|
||||
serializer = TopicViewSerializer.new(
|
||||
serializer =
|
||||
TopicViewSerializer.new(
|
||||
TopicView.new(topic.id, user),
|
||||
scope: Guardian.new(user),
|
||||
root: false
|
||||
root: false,
|
||||
).as_json
|
||||
|
||||
expect(serializer[:topic_field_1]).to eq(true)
|
||||
|
@ -40,11 +43,8 @@ describe "custom field extensions" do
|
|||
topic.custom_fields["topic_field_1"] = true
|
||||
topic.save_custom_fields(true)
|
||||
|
||||
serializer = TopicListItemSerializer.new(
|
||||
topic,
|
||||
scope: Guardian.new(user),
|
||||
root: false
|
||||
).as_json
|
||||
serializer =
|
||||
TopicListItemSerializer.new(topic, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(serializer[:topic_field_1]).to eq(true)
|
||||
end
|
||||
|
@ -60,11 +60,7 @@ describe "custom field extensions" do
|
|||
post.custom_fields["post_field_1"] = 7
|
||||
post.save_custom_fields(true)
|
||||
|
||||
serializer = PostSerializer.new(
|
||||
post,
|
||||
scope: Guardian.new(user),
|
||||
root: false
|
||||
).as_json
|
||||
serializer = PostSerializer.new(post, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(serializer[:post_field_1]).to eq(7)
|
||||
end
|
||||
|
@ -74,7 +70,7 @@ describe "custom field extensions" do
|
|||
before do
|
||||
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.save
|
||||
end
|
||||
|
@ -90,11 +86,8 @@ describe "custom field extensions" do
|
|||
category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json
|
||||
category.save_custom_fields(true)
|
||||
|
||||
serializer = BasicCategorySerializer.new(
|
||||
category,
|
||||
scope: Guardian.new(user),
|
||||
root: false
|
||||
).as_json
|
||||
serializer =
|
||||
BasicCategorySerializer.new(category, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json)
|
||||
end
|
||||
|
@ -110,11 +103,7 @@ describe "custom field extensions" do
|
|||
group.custom_fields["group_field_1"] = "Hello"
|
||||
group.save_custom_fields(true)
|
||||
|
||||
serializer = BasicGroupSerializer.new(
|
||||
group,
|
||||
scope: Guardian.new(user),
|
||||
root: false
|
||||
).as_json
|
||||
serializer = BasicGroupSerializer.new(group, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(serializer[:group_field_1]).to eq("Hello")
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe ::DiscourseTagging, type: :request do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
fab!(:tag_1) { Fabricate(:tag, name: "Angus") }
|
||||
fab!(:tag_2) { Fabricate(:tag, name: "Faizaan") }
|
||||
fab!(:tag_3) { Fabricate(:tag, name: "Robert") }
|
||||
|
@ -16,10 +16,7 @@ describe ::DiscourseTagging, type: :request do
|
|||
|
||||
context "for_input is a boolean" do
|
||||
it "works normally" do
|
||||
filter_params = {
|
||||
q: '',
|
||||
for_input: true
|
||||
}
|
||||
filter_params = { q: "", for_input: true }
|
||||
tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params)
|
||||
names = tags.map(&:name)
|
||||
all_tag_names = Tag.all.pluck(:name)
|
||||
|
@ -33,15 +30,17 @@ describe ::DiscourseTagging, type: :request do
|
|||
q: "",
|
||||
for_input: {
|
||||
name: "custom-wizard-tag-chooser",
|
||||
groups: tag_group_1.name
|
||||
}
|
||||
groups: tag_group_1.name,
|
||||
},
|
||||
}
|
||||
tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params)
|
||||
names = tags.map(&:name)
|
||||
expected_tag_names = TagGroup
|
||||
expected_tag_names =
|
||||
TagGroup
|
||||
.includes(:tags)
|
||||
.where(id: tag_group_1.id)
|
||||
.map { |tag_group| tag_group.tags.pluck(:name) }.flatten
|
||||
.map { |tag_group| tag_group.tags.pluck(:name) }
|
||||
.flatten
|
||||
|
||||
expect(names).to contain_exactly(*expected_tag_names)
|
||||
end
|
||||
|
@ -49,13 +48,7 @@ describe ::DiscourseTagging, type: :request do
|
|||
|
||||
context "for_input is an object including an empty tag group string" do
|
||||
it "returns all tags" do
|
||||
filter_params = {
|
||||
q: "",
|
||||
for_input: {
|
||||
name: "custom-wizard-tag-chooser",
|
||||
groups: ""
|
||||
}
|
||||
}
|
||||
filter_params = { q: "", for_input: { name: "custom-wizard-tag-chooser", groups: "" } }
|
||||
tags = DiscourseTagging.filter_allowed_tags(guardian, filter_params)
|
||||
names = tags.map(&:name)
|
||||
|
||||
|
|
|
@ -6,9 +6,7 @@ describe ExtraLocalesControllerCustomWizard, type: :request do
|
|||
let(:template) { get_wizard_fixture("wizard") }
|
||||
let(:permitted) { get_wizard_fixture("wizard/permitted") }
|
||||
|
||||
before do
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
end
|
||||
before { CustomWizard::Template.save(template, skip_jobs: true) }
|
||||
|
||||
before do
|
||||
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
|
||||
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)
|
||||
end
|
||||
|
||||
it "returns wizard locales when requested by user in a wizard step" do
|
||||
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)
|
||||
end
|
||||
|
||||
|
@ -38,7 +36,7 @@ describe ExtraLocalesControllerCustomWizard, type: :request do
|
|||
CustomWizard::Template.save(template.as_json)
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,40 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe ::Guardian do
|
||||
fab!(:user) {
|
||||
Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com")
|
||||
}
|
||||
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') }
|
||||
let(:wizard_template) {
|
||||
fab!(:user) { Fabricate(:user, name: "Angus", username: "angus", email: "angus@email.com") }
|
||||
fab!(:category) { Fabricate(:category, name: "cat1", slug: "cat-slug") }
|
||||
let(:wizard_template) do
|
||||
JSON.parse(
|
||||
File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
||||
).read
|
||||
File.open("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json").read,
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
def create_topic_by_wizard(wizard)
|
||||
wizard.create_updater(
|
||||
wizard.steps.first.id,
|
||||
step_1_field_1: "Topic Title",
|
||||
step_1_field_2: "topic body"
|
||||
step_1_field_2: "topic body",
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.second.id, {}).update
|
||||
wizard.create_updater(wizard.steps.last.id,
|
||||
step_3_field_3: category.id
|
||||
).update
|
||||
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id).update
|
||||
|
||||
topic = Topic.where(
|
||||
title: "Topic Title",
|
||||
category_id: category.id
|
||||
).first
|
||||
topic = Topic.where(title: "Topic Title", category_id: category.id).first
|
||||
|
||||
topic
|
||||
end
|
||||
|
||||
before do
|
||||
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
|
||||
|
||||
context "topic created by user using wizard" do
|
||||
|
@ -47,11 +38,7 @@ describe ::Guardian do
|
|||
|
||||
context "topic created by user without wizard" do
|
||||
it "restricts editing the topic first post" do
|
||||
topic_params = {
|
||||
title: "Topic Title",
|
||||
raw: "Topic body",
|
||||
skip_validations: true
|
||||
}
|
||||
topic_params = { title: "Topic Title", raw: "Topic body", skip_validations: true }
|
||||
post = PostCreator.new(user, topic_params).create
|
||||
expect(user.guardian.wizard_can_edit_topic?(post.topic)).to be_falsey
|
||||
end
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe InvitesControllerCustomWizard, type: :request do
|
||||
fab!(:topic) { Fabricate(:topic) }
|
||||
fab!(:topic)
|
||||
let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) }
|
||||
let(:template) { get_wizard_fixture("wizard") }
|
||||
|
||||
before do
|
||||
@controller = InvitesController.new
|
||||
end
|
||||
before { @controller = InvitesController.new }
|
||||
|
||||
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)
|
||||
put "/invites/show/#{invite.invite_key}.json"
|
||||
expect(cookies[:destination_url]).to eq("/w/super-mega-fun-wizard")
|
||||
|
|
|
@ -2,42 +2,39 @@
|
|||
|
||||
describe Topic, type: :model do
|
||||
fab!(:category_with_wizard) do
|
||||
Fabricate(:category, custom_fields: { create_topic_wizard: 'true' })
|
||||
Fabricate(:category, custom_fields: { create_topic_wizard: "true" })
|
||||
end
|
||||
fab!(:category_without_wizard) { Fabricate(:category) }
|
||||
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
|
||||
let(:valid_attrs) { Fabricate.attributes_for(:topic) }
|
||||
|
||||
context 'with a create_topic_wizard custom field in the category' do
|
||||
it 'will not allow creating a topic directly' do
|
||||
context "with a create_topic_wizard custom field in the category" do
|
||||
it "will not allow creating a topic directly" do
|
||||
expect do
|
||||
TopicCreator.create(
|
||||
user,
|
||||
Guardian.new(user),
|
||||
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,
|
||||
raw: 'hello this is a test topic with category with custom fields'
|
||||
)
|
||||
)
|
||||
end.to raise_error(
|
||||
Discourse::InvalidParameters,
|
||||
'Category not allowed for topic creation.'
|
||||
raw: "hello this is a test topic with category with custom fields",
|
||||
),
|
||||
)
|
||||
end.to raise_error(Discourse::InvalidParameters, "Category not allowed for topic creation.")
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a create_topic_wizard custom field in the category' do
|
||||
it 'will allow creating a topic directly' do
|
||||
context "without a create_topic_wizard custom field in the category" do
|
||||
it "will allow creating a topic directly" do
|
||||
expect do
|
||||
TopicCreator.create(
|
||||
user,
|
||||
Guardian.new(user),
|
||||
valid_attrs.merge(
|
||||
category: category_without_wizard.id,
|
||||
title: 'Another valid and sufficiently long title for testing',
|
||||
raw: 'This is the body of a valid topic'
|
||||
)
|
||||
title: "Another valid and sufficiently long title for testing",
|
||||
raw: "This is the body of a valid topic",
|
||||
),
|
||||
)
|
||||
end.not_to raise_error
|
||||
end
|
||||
|
|
|
@ -3,12 +3,10 @@
|
|||
describe CustomWizardUsersController, type: :request do
|
||||
let(:template) { get_wizard_fixture("wizard") }
|
||||
|
||||
before do
|
||||
@controller = UsersController.new
|
||||
end
|
||||
before { @controller = UsersController.new }
|
||||
|
||||
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)
|
||||
sign_in(Fabricate(:user))
|
||||
get "/u/account-created"
|
||||
|
|
20
spec/fixtures/subscription_client.rb
gevendort
20
spec/fixtures/subscription_client.rb
gevendort
|
@ -5,32 +5,32 @@ module DiscourseSubscriptionClient
|
|||
end
|
||||
end
|
||||
|
||||
SubscriptionClientSupplier = Class.new Object do
|
||||
SubscriptionClientSupplier =
|
||||
Class.new Object do
|
||||
attr_reader :product_slugs
|
||||
|
||||
def initialize(product_slugs)
|
||||
@product_slugs = product_slugs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SubscriptionClientResource = Class.new Object do
|
||||
end
|
||||
SubscriptionClientResource =
|
||||
Class.new Object do
|
||||
end
|
||||
|
||||
SubscriptionClientSubscription = Class.new Object do
|
||||
SubscriptionClientSubscription =
|
||||
Class.new Object do
|
||||
attr_reader :product_id
|
||||
|
||||
def initialize(product_id)
|
||||
@product_id = product_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module DiscourseSubscriptionClient
|
||||
class Subscriptions
|
||||
class Result
|
||||
attr_accessor :supplier,
|
||||
:resource,
|
||||
:subscriptions,
|
||||
:products
|
||||
attr_accessor :supplier, :resource, :subscriptions, :products
|
||||
|
||||
def any?
|
||||
supplier.present? && resource.present? && subscriptions.present? && products.present?
|
||||
|
|
|
@ -16,16 +16,14 @@ describe Jobs::SetAfterTimeWizard do
|
|||
end
|
||||
|
||||
it "sets wizard redirect for all users " do
|
||||
messages = MessageBus.track_publish("/redirect_to_wizard") do
|
||||
described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
|
||||
messages =
|
||||
MessageBus.track_publish("/redirect_to_wizard") do
|
||||
described_class.new.execute(wizard_id: "super_mega_fun_wizard")
|
||||
end
|
||||
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(
|
||||
UserCustomField.where(
|
||||
name: 'redirect_to_wizard',
|
||||
value: 'super_mega_fun_wizard'
|
||||
).length
|
||||
UserCustomField.where(name: "redirect_to_wizard", value: "super_mega_fun_wizard").length,
|
||||
).to eq(3)
|
||||
end
|
||||
|
||||
|
@ -37,16 +35,14 @@ describe Jobs::SetAfterTimeWizard do
|
|||
end
|
||||
|
||||
it "only redirects users in the group" do
|
||||
messages = MessageBus.track_publish("/redirect_to_wizard") do
|
||||
described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
|
||||
messages =
|
||||
MessageBus.track_publish("/redirect_to_wizard") do
|
||||
described_class.new.execute(wizard_id: "super_mega_fun_wizard")
|
||||
end
|
||||
expect(messages.first.data).to eq("super_mega_fun_wizard")
|
||||
expect(messages.first.user_ids).to match_array([user2.id])
|
||||
expect(
|
||||
UserCustomField.where(
|
||||
name: 'redirect_to_wizard',
|
||||
value: 'super_mega_fun_wizard'
|
||||
).length
|
||||
UserCustomField.where(name: "redirect_to_wizard", value: "super_mega_fun_wizard").length,
|
||||
).to eq(1)
|
||||
end
|
||||
end
|
||||
|
@ -58,22 +54,20 @@ describe Jobs::SetAfterTimeWizard do
|
|||
action: CustomWizard::UserHistory.actions[:step],
|
||||
actor_id: user1.id,
|
||||
context: @after_time_template[:id],
|
||||
subject: step[:id]
|
||||
subject: step[:id],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not redirect to user" do
|
||||
messages = MessageBus.track_publish("/redirect_to_wizard") do
|
||||
described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
|
||||
messages =
|
||||
MessageBus.track_publish("/redirect_to_wizard") do
|
||||
described_class.new.execute(wizard_id: "super_mega_fun_wizard")
|
||||
end
|
||||
expect(messages.first.data).to eq("super_mega_fun_wizard")
|
||||
expect(messages.first.user_ids).to match_array([user2.id, user3.id])
|
||||
expect(
|
||||
UserCustomField.where(
|
||||
name: 'redirect_to_wizard',
|
||||
value: 'super_mega_fun_wizard'
|
||||
).length
|
||||
UserCustomField.where(name: "redirect_to_wizard", value: "super_mega_fun_wizard").length,
|
||||
).to eq(2)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
def get_wizard_fixture(path)
|
||||
JSON.parse(
|
||||
File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/#{path}.json"
|
||||
).read
|
||||
File.open("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/#{path}.json").read,
|
||||
).with_indifferent_access
|
||||
end
|
||||
|
||||
|
@ -14,11 +12,7 @@ def enable_subscription(type)
|
|||
end
|
||||
|
||||
def disable_subscriptions
|
||||
%w[
|
||||
standard
|
||||
business
|
||||
community
|
||||
].each do |type|
|
||||
%w[standard business community].each do |type|
|
||||
CustomWizard::Subscription.stubs("#{type}?".to_sym).returns(false)
|
||||
CustomWizard::Subscription.any_instance.stubs("#{type}?".to_sym).returns(false)
|
||||
end
|
||||
|
|
|
@ -4,9 +4,7 @@ describe CustomWizard::AdminApiController do
|
|||
fab!(:admin_user) { Fabricate(:user, admin: true) }
|
||||
let(:api_json) { get_wizard_fixture("api/api") }
|
||||
|
||||
before do
|
||||
sign_in(admin_user)
|
||||
end
|
||||
before { sign_in(admin_user) }
|
||||
|
||||
it "does not save if user does not have relevant subscription" do
|
||||
disable_subscriptions
|
||||
|
|
|
@ -5,7 +5,7 @@ describe CustomWizard::AdminCustomFieldsController do
|
|||
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
|
||||
|
||||
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
|
||||
end
|
||||
sign_in(admin_user)
|
||||
|
@ -17,25 +17,19 @@ describe CustomWizard::AdminCustomFieldsController do
|
|||
end
|
||||
|
||||
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['type'] = 'string'
|
||||
topic_field_json["type"] = "string"
|
||||
|
||||
put "/admin/wizards/custom-fields.json", params: {
|
||||
custom_field: topic_field_json
|
||||
}
|
||||
put "/admin/wizards/custom-fields.json", params: { custom_field: topic_field_json }
|
||||
expect(response.status).to eq(200)
|
||||
expect(
|
||||
CustomWizard::CustomField.find_by_name('topic_field_1').type
|
||||
).to eq('string')
|
||||
expect(CustomWizard::CustomField.find_by_name("topic_field_1").type).to eq("string")
|
||||
end
|
||||
|
||||
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"
|
||||
expect(response.status).to eq(200)
|
||||
expect(
|
||||
CustomWizard::CustomField.exists?('topic_field_1')
|
||||
).to eq(false)
|
||||
expect(CustomWizard::CustomField.exists?("topic_field_1")).to eq(false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,11 +5,16 @@ describe CustomWizard::AdminLogsController do
|
|||
let(:template) { get_wizard_fixture("wizard") }
|
||||
|
||||
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["id"] = "#{key}_test_wizard"
|
||||
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
|
||||
sign_in(admin_user)
|
||||
end
|
||||
|
@ -21,21 +26,21 @@ describe CustomWizard::AdminLogsController do
|
|||
|
||||
it "returns a list of logs for a wizard" do
|
||||
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
|
||||
|
||||
it "paginates" do
|
||||
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
|
||||
|
||||
it "returns total logs for a wizard" do
|
||||
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
|
||||
|
||||
it "returns basic wizard" do
|
||||
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
|
||||
|
|
|
@ -8,27 +8,22 @@ describe CustomWizard::AdminManagerController do
|
|||
sign_in(admin_user)
|
||||
|
||||
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["id"] = 'super_mega_fun_wizard_3'
|
||||
template_3["id"] = "super_mega_fun_wizard_3"
|
||||
@template_array = [template, template_2, template_3]
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
it 'exports all the wizard templates' do
|
||||
@template_array.each do |template|
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
end
|
||||
it "exports all the wizard templates" do
|
||||
@template_array.each { |template| CustomWizard::Template.save(template, skip_jobs: true) }
|
||||
|
||||
get '/admin/wizards/manager/export.json', params: {
|
||||
wizard_ids: [
|
||||
'super_mega_fun_wizard',
|
||||
'super_mega_fun_wizard_2',
|
||||
'super_mega_fun_wizard_3'
|
||||
]
|
||||
get "/admin/wizards/manager/export.json",
|
||||
params: {
|
||||
wizard_ids: %w[super_mega_fun_wizard super_mega_fun_wizard_2 super_mega_fun_wizard_3],
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -37,60 +32,60 @@ describe CustomWizard::AdminManagerController do
|
|||
|
||||
context "import" 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: {
|
||||
file: fixture_file_upload(File.open(@tmp_file_path))
|
||||
post "/admin/wizards/manager/import.json",
|
||||
params: {
|
||||
file: fixture_file_upload(File.open(@tmp_file_path)),
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body['imported']).to match_array(templates)
|
||||
expect(CustomWizard::Template.list.map { |t| t.slice('id', 'name') }).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,
|
||||
)
|
||||
end
|
||||
|
||||
it 'rejects a template with the same id as a saved template' do
|
||||
templates = @template_array.map { |t| t.slice('id', 'name') }
|
||||
it "rejects a template with the same id as a saved template" do
|
||||
templates = @template_array.map { |t| t.slice("id", "name") }
|
||||
|
||||
post '/admin/wizards/manager/import.json', params: {
|
||||
file: fixture_file_upload(File.open(@tmp_file_path))
|
||||
post "/admin/wizards/manager/import.json",
|
||||
params: {
|
||||
file: fixture_file_upload(File.open(@tmp_file_path)),
|
||||
}
|
||||
|
||||
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: {
|
||||
file: fixture_file_upload(File.open(@tmp_file_path))
|
||||
post "/admin/wizards/manager/import.json",
|
||||
params: {
|
||||
file: fixture_file_upload(File.open(@tmp_file_path)),
|
||||
}
|
||||
|
||||
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|
|
||||
{
|
||||
id: t['id'],
|
||||
messages: I18n.t("wizard.validation.conflict", wizard_id: t['id'])
|
||||
id: t["id"],
|
||||
messages: I18n.t("wizard.validation.conflict", wizard_id: t["id"]),
|
||||
}.as_json
|
||||
end
|
||||
end,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it 'destroys wizard templates' do
|
||||
templates = @template_array.map { |t| t.slice('id', 'name') }
|
||||
it "destroys wizard templates" do
|
||||
templates = @template_array.map { |t| t.slice("id", "name") }
|
||||
|
||||
@template_array.each do |template|
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
end
|
||||
@template_array.each { |template| CustomWizard::Template.save(template, skip_jobs: true) }
|
||||
|
||||
delete '/admin/wizards/manager/destroy.json', params: {
|
||||
wizard_ids: [
|
||||
'super_mega_fun_wizard',
|
||||
'super_mega_fun_wizard_2',
|
||||
'super_mega_fun_wizard_3'
|
||||
]
|
||||
delete "/admin/wizards/manager/destroy.json",
|
||||
params: {
|
||||
wizard_ids: %w[super_mega_fun_wizard super_mega_fun_wizard_2 super_mega_fun_wizard_3],
|
||||
}
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,26 +9,22 @@ describe CustomWizard::SubscriptionController do
|
|||
end
|
||||
|
||||
context "with an admin" do
|
||||
before do
|
||||
sign_in(admin_user)
|
||||
end
|
||||
before { sign_in(admin_user) }
|
||||
|
||||
context "without a subscription" do
|
||||
before do
|
||||
disable_subscriptions
|
||||
end
|
||||
before { disable_subscriptions }
|
||||
|
||||
it "returns the right subscription details" do
|
||||
get "/admin/wizards/subscription.json"
|
||||
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
|
||||
|
||||
context "with a subscription" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
end
|
||||
before { enable_subscription("standard") }
|
||||
|
||||
it "returns the right subscription details" do
|
||||
get "/admin/wizards/subscription.json"
|
||||
|
|
|
@ -5,18 +5,25 @@ describe CustomWizard::AdminWizardController do
|
|||
fab!(:user1) { Fabricate(:user) }
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
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
|
||||
enable_subscription("standard")
|
||||
CustomWizard::Template.save(template, skip_jobs: true)
|
||||
template_2 = template.dup
|
||||
template_2["id"] = 'super_mega_fun_wizard_2'
|
||||
template_2["permitted"] = template_2['permitted']
|
||||
template_2["id"] = "super_mega_fun_wizard_2"
|
||||
template_2["permitted"] = template_2["permitted"]
|
||||
CustomWizard::Template.save(template_2, skip_jobs: true)
|
||||
|
||||
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
|
||||
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
|
||||
get "/admin/wizards/wizard.json"
|
||||
expect(
|
||||
response.parsed_body['wizard_list'].map { |w| w['id'] }
|
||||
).to match_array(['super_mega_fun_wizard', 'super_mega_fun_wizard_2', 'super_mega_fun_wizard_3'])
|
||||
expect(
|
||||
response.parsed_body['field_types'].keys
|
||||
).to eq(CustomWizard::Field.types.keys.map(&:to_s))
|
||||
expect(response.parsed_body["wizard_list"].map { |w| w["id"] }).to match_array(
|
||||
%w[super_mega_fun_wizard super_mega_fun_wizard_2 super_mega_fun_wizard_3],
|
||||
)
|
||||
expect(response.parsed_body["field_types"].keys).to eq(
|
||||
CustomWizard::Field.types.keys.map(&:to_s),
|
||||
)
|
||||
end
|
||||
|
||||
it "returns a wizard template" do
|
||||
get "/admin/wizards/wizard/#{template['id']}.json"
|
||||
expect(response.parsed_body['id']).to eq(template['id'])
|
||||
expect(response.parsed_body['steps'].length).to eq(3)
|
||||
get "/admin/wizards/wizard/#{template["id"]}.json"
|
||||
expect(response.parsed_body["id"]).to eq(template["id"])
|
||||
expect(response.parsed_body["steps"].length).to eq(3)
|
||||
end
|
||||
|
||||
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)
|
||||
delete "/admin/wizards/wizard/#{template['id']}.json"
|
||||
expect(
|
||||
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(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(CustomWizard::Template.exists?(template["id"])).to eq(false)
|
||||
expect(
|
||||
CategoryCustomField.find_by(
|
||||
name: "create_topic_wizard",
|
||||
value: template["name"].parameterize(separator: "_"),
|
||||
),
|
||||
).to eq(nil)
|
||||
end
|
||||
|
||||
it "saves wizard templates" do
|
||||
template_updated = template.dup
|
||||
template_updated['name'] = "Super Mega Fun Wizard 2"
|
||||
template_updated['multiple_submissions'] = false
|
||||
template_updated['steps'][0]['fields'][0]['label'] = "Text 2"
|
||||
template_updated["name"] = "Super Mega Fun Wizard 2"
|
||||
template_updated["multiple_submissions"] = false
|
||||
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)
|
||||
|
||||
updated_template = CustomWizard::Template.find('super_mega_fun_wizard')
|
||||
expect(updated_template['name']).to eq("Super Mega Fun Wizard 2")
|
||||
expect(updated_template['multiple_submissions']).to eq("false")
|
||||
expect(updated_template['steps'][0]['fields'][0]['label']).to eq("Text 2")
|
||||
updated_template = CustomWizard::Template.find("super_mega_fun_wizard")
|
||||
expect(updated_template["name"]).to eq("Super Mega Fun Wizard 2")
|
||||
expect(updated_template["multiple_submissions"]).to eq("false")
|
||||
expect(updated_template["steps"][0]["fields"][0]["label"]).to eq("Text 2")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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(:permitted_json) { get_wizard_fixture("wizard/permitted") }
|
||||
|
||||
before do
|
||||
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
|
||||
|
||||
context "with signed in user" do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
before { sign_in(user) }
|
||||
|
||||
context "who is required to complete wizard" 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)
|
||||
end
|
||||
|
||||
|
@ -55,10 +55,9 @@ describe ApplicationController do
|
|||
end
|
||||
|
||||
it "saves original destination of user" do
|
||||
get '/', headers: { 'REFERER' => "/t/2" }
|
||||
get "/", headers: { "REFERER" => "/t/2" }
|
||||
expect(
|
||||
CustomWizard::Wizard.create(@template['id'], user).submissions
|
||||
.first.redirect_to
|
||||
CustomWizard::Wizard.create(@template["id"], user).submissions.first.redirect_to,
|
||||
).to eq("/t/2")
|
||||
end
|
||||
end
|
||||
|
@ -101,9 +100,7 @@ describe ApplicationController do
|
|||
end
|
||||
|
||||
context "when user is not in permitted group" do
|
||||
before do
|
||||
Group.find(13).remove(user)
|
||||
end
|
||||
before { Group.find(13).remove(user) }
|
||||
|
||||
it "does not redirect user" do
|
||||
travel_to Time.now + 4.hours
|
||||
|
@ -131,7 +128,7 @@ describe ApplicationController do
|
|||
action: CustomWizard::UserHistory.actions[:step],
|
||||
actor_id: user.id,
|
||||
context: @template[:id],
|
||||
subject: step[:id]
|
||||
subject: step[:id],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,12 @@ describe "custom field extensions" do
|
|||
let!(:user) { Fabricate(:user) }
|
||||
let!(:group) { Fabricate(:group, users: [user]) }
|
||||
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
|
||||
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.save
|
||||
end
|
||||
|
@ -33,13 +35,13 @@ describe "custom field extensions" do
|
|||
get "/posts/#{post.id}.json"
|
||||
|
||||
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
|
||||
|
||||
context "with a subscription" do
|
||||
before do
|
||||
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.save
|
||||
end
|
||||
|
@ -63,7 +65,7 @@ describe "custom field extensions" do
|
|||
get "/groups/#{group.name}.json"
|
||||
|
||||
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
|
||||
|
||||
context "preloaded" do
|
||||
|
@ -76,7 +78,8 @@ describe "custom field extensions" do
|
|||
get "/site.json"
|
||||
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)
|
||||
end
|
||||
|
||||
|
@ -90,8 +93,8 @@ describe "custom field extensions" do
|
|||
get "/groups.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
group = response.parsed_body['groups'].select { |g| g['id'] == group.id }.first
|
||||
expect(group['group_field_1']).to eq("Group cf entry")
|
||||
group = response.parsed_body["groups"].select { |g| g["id"] == group.id }.first
|
||||
expect(group["group_field_1"]).to eq("Group cf entry")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::RealtimeValidationsController do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
let(:validation_type) { "test_stub" }
|
||||
let(:validation_type_stub) {
|
||||
{
|
||||
types: [:text],
|
||||
component: "similar-topics-validator",
|
||||
backend: true,
|
||||
required_params: []
|
||||
}
|
||||
}
|
||||
let(:validation_type_stub) do
|
||||
{ types: [:text], component: "similar-topics-validator", backend: true, required_params: [] }
|
||||
end
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
|
@ -24,7 +19,7 @@ describe CustomWizard::RealtimeValidationsController do
|
|||
|
||||
def perform(params)
|
||||
result = CustomWizard::RealtimeValidation::Result.new(:test_stub)
|
||||
result.items = ["hello", "world"]
|
||||
result.items = %w[hello world]
|
||||
result
|
||||
end
|
||||
end
|
||||
|
@ -40,25 +35,22 @@ describe CustomWizard::RealtimeValidationsController do
|
|||
|
||||
it "gives the correct response for a given type" do
|
||||
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)
|
||||
expected_response = [
|
||||
{ "item" => "hello" },
|
||||
{ "item" => "world" }
|
||||
]
|
||||
expected_response = [{ "item" => "hello" }, { "item" => "world" }]
|
||||
expect(JSON.parse(response.body)).to eq(expected_response)
|
||||
end
|
||||
|
||||
it "gives 400 error when no type is passed" do
|
||||
CustomWizard::RealtimeValidation.types = { test_stub: validation_type_stub }
|
||||
get '/realtime-validations.json'
|
||||
get "/realtime-validations.json"
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
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][: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)
|
||||
# the addition is only relevant to this test, so getting rid of it
|
||||
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
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::StepsController do
|
||||
fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) }
|
||||
fab!(:user2) { Fabricate(:user, username: 'bob', email: "bob@email.com", trust_level: TrustLevel[2]) }
|
||||
fab!(:user) do
|
||||
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_field_condition_template) { get_wizard_fixture("condition/wizard_field_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(:guests_permitted) { get_wizard_fixture("wizard/guests_permitted") }
|
||||
|
||||
before do
|
||||
CustomWizard::Template.save(wizard_template, skip_jobs: true)
|
||||
end
|
||||
before { CustomWizard::Template.save(wizard_template, skip_jobs: true) }
|
||||
|
||||
def guest_template
|
||||
temp = wizard_template.dup
|
||||
|
@ -25,10 +27,11 @@ describe CustomWizard::StepsController do
|
|||
|
||||
context "with guest" 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",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Text input"
|
||||
}
|
||||
step_1_field_1: "Text input",
|
||||
},
|
||||
}
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
@ -40,22 +43,23 @@ describe CustomWizard::StepsController do
|
|||
end
|
||||
|
||||
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",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Text input"
|
||||
}
|
||||
step_1_field_1: "Text input",
|
||||
},
|
||||
}
|
||||
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])
|
||||
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
|
||||
|
||||
context "raises an error" 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)
|
||||
end
|
||||
|
||||
|
@ -65,74 +69,74 @@ describe CustomWizard::StepsController do
|
|||
new_template["permitted"] = permitted_json["permitted"]
|
||||
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)
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
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.parsed_body['wizard']['start']).to eq("step_2")
|
||||
expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
|
||||
end
|
||||
|
||||
it "returns an updated wizard when condition passes" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will pass"
|
||||
}
|
||||
step_1_field_1: "Condition will pass",
|
||||
},
|
||||
}
|
||||
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
|
||||
|
||||
it "runs completion actions if guest has completed wizard" do
|
||||
new_template = guest_template.dup
|
||||
|
||||
## 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)
|
||||
|
||||
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_3.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_3.json"
|
||||
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
|
||||
|
||||
context "with user" do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
before { sign_in(user) }
|
||||
|
||||
it 'performs a step update' do
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
it "performs a step update" do
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Text input"
|
||||
}
|
||||
step_1_field_1: "Text input",
|
||||
},
|
||||
}
|
||||
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)
|
||||
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
|
||||
|
||||
context "raises an error" 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)
|
||||
end
|
||||
|
||||
|
@ -142,120 +146,121 @@ describe CustomWizard::StepsController do
|
|||
new_template["permitted"] = admin_permitted_json["permitted"]
|
||||
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)
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
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.parsed_body['wizard']['start']).to eq("step_2")
|
||||
expect(response.parsed_body["wizard"]["start"]).to eq("step_2")
|
||||
end
|
||||
|
||||
it "returns an updated wizard when condition passes" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will pass"
|
||||
}
|
||||
step_1_field_1: "Condition will pass",
|
||||
},
|
||||
}
|
||||
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
|
||||
|
||||
it "runs completion actions if user has completed wizard" do
|
||||
new_template = wizard_template.dup
|
||||
|
||||
## 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)
|
||||
|
||||
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_3.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_3.json"
|
||||
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
|
||||
|
||||
it "saves results of completion actions if user has completed wizard" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Topic title",
|
||||
step_1_field_2: "Topic post"
|
||||
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)
|
||||
|
||||
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)
|
||||
expect(topic.present?).to eq(true)
|
||||
end
|
||||
|
||||
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.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.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.parsed_body['final']).to eq(true)
|
||||
expect(response.parsed_body["final"]).to eq(true)
|
||||
end
|
||||
|
||||
context "subscription" do
|
||||
before do
|
||||
enable_subscription("standard")
|
||||
end
|
||||
before { enable_subscription("standard") }
|
||||
|
||||
it "raises an error when user cant see the step due to conditions" do
|
||||
sign_in(user2)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
it "returns an updated wizard when condition doesnt pass" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition wont pass"
|
||||
}
|
||||
step_1_field_1: "Condition wont pass",
|
||||
},
|
||||
}
|
||||
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
|
||||
|
||||
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['steps'][0]['condition'] = user_condition_template['condition']
|
||||
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
|
||||
new_template["steps"][0]["condition"] = user_condition_template["condition"]
|
||||
new_template["steps"][2]["condition"] = wizard_field_condition_template["condition"]
|
||||
CustomWizard::Template.save(new_template, skip_jobs: true)
|
||||
end
|
||||
|
||||
|
@ -263,107 +268,116 @@ describe CustomWizard::StepsController do
|
|||
sign_in(user2)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
it "returns an updated wizard when condition doesnt pass" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition wont pass"
|
||||
}
|
||||
step_1_field_1: "Condition wont pass",
|
||||
},
|
||||
}
|
||||
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
|
||||
|
||||
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['steps'][0]['condition'] = user_condition_template['condition']
|
||||
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
|
||||
new_template["steps"][0]["condition"] = user_condition_template["condition"]
|
||||
new_template["steps"][2]["condition"] = wizard_field_condition_template["condition"]
|
||||
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",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will pass"
|
||||
}
|
||||
step_1_field_1: "Condition will pass",
|
||||
},
|
||||
}
|
||||
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.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.parsed_body['final']).to eq(true)
|
||||
expect(response.parsed_body["final"]).to eq(true)
|
||||
end
|
||||
|
||||
it "returns the correct final step when the conditional final step and last step are different" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will not pass"
|
||||
}
|
||||
step_1_field_1: "Condition will not pass",
|
||||
},
|
||||
}
|
||||
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.parsed_body['final']).to eq(true)
|
||||
expect(response.parsed_body["final"]).to eq(true)
|
||||
end
|
||||
|
||||
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['steps'][1]['condition'] = wizard_field_condition_template['condition']
|
||||
new_template['steps'][2]['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"]
|
||||
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",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will not pass"
|
||||
}
|
||||
step_1_field_1: "Condition will not pass",
|
||||
},
|
||||
}
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body['final']).to eq(true)
|
||||
expect(response.parsed_body["final"]).to eq(true)
|
||||
end
|
||||
|
||||
it "excludes the non-included conditional fields from the submissions" do
|
||||
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)
|
||||
|
||||
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
|
||||
put "/w/super-mega-fun-wizard/steps/step_1.json",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will pass"
|
||||
}
|
||||
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",
|
||||
params: {
|
||||
fields: {
|
||||
step_2_field_1: "1995-04-23"
|
||||
}
|
||||
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",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Condition will not pass"
|
||||
}
|
||||
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)
|
||||
submission = wizard.current_submission
|
||||
expect(submission.fields.keys).not_to include("step_2_field_1")
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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(:permitted_json) { get_wizard_fixture("wizard/permitted") }
|
||||
|
||||
|
@ -10,66 +12,62 @@ describe CustomWizard::WizardController do
|
|||
@template = CustomWizard::Template.find("super_mega_fun_wizard")
|
||||
end
|
||||
|
||||
context 'plugin disabled' do
|
||||
before do
|
||||
SiteSetting.custom_wizard_enabled = false
|
||||
end
|
||||
context "plugin disabled" do
|
||||
before { SiteSetting.custom_wizard_enabled = false }
|
||||
|
||||
it 'redirects to root' do
|
||||
get '/w/super-mega-fun-wizard', xhr: true
|
||||
it "redirects to root" do
|
||||
get "/w/super-mega-fun-wizard", xhr: true
|
||||
expect(response).to redirect_to("/")
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns wizard' do
|
||||
get '/w/super-mega-fun-wizard.json'
|
||||
it "returns wizard" do
|
||||
get "/w/super-mega-fun-wizard.json"
|
||||
expect(response.parsed_body["id"]).to eq("super_mega_fun_wizard")
|
||||
end
|
||||
|
||||
it 'returns missing message if no wizard exists' do
|
||||
get '/w/super-mega-fun-wizards.json'
|
||||
it "returns missing message if no wizard exists" do
|
||||
get "/w/super-mega-fun-wizards.json"
|
||||
expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.")
|
||||
end
|
||||
|
||||
context "with user" do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
before { sign_in(user) }
|
||||
|
||||
context 'when user skips' do
|
||||
it 'skips a wizard if user is allowed to skip' do
|
||||
put '/w/super-mega-fun-wizard/skip.json'
|
||||
context "when user skips" do
|
||||
it "skips a wizard if user is allowed to skip" do
|
||||
put "/w/super-mega-fun-wizard/skip.json"
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
|
||||
it 'lets user skip if user cant access wizard' do
|
||||
it "lets user skip if user cant access wizard" do
|
||||
enable_subscription("standard")
|
||||
@template["permitted"] = permitted_json["permitted"]
|
||||
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)
|
||||
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")
|
||||
@template['required'] = 'true'
|
||||
@template["required"] = "true"
|
||||
CustomWizard::Template.save(@template)
|
||||
put '/w/super-mega-fun-wizard/skip.json'
|
||||
expect(response.parsed_body['error']).to eq("Wizard can't be skipped")
|
||||
put "/w/super-mega-fun-wizard/skip.json"
|
||||
expect(response.parsed_body["error"]).to eq("Wizard can't be skipped")
|
||||
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)
|
||||
CustomWizard::Submission.new(@wizard, redirect_to: "/t/2").save
|
||||
put '/w/super-mega-fun-wizard/skip.json'
|
||||
expect(response.parsed_body['redirect_to']).to eq('/t/2')
|
||||
put "/w/super-mega-fun-wizard/skip.json"
|
||||
expect(response.parsed_body["redirect_to"]).to eq("/t/2")
|
||||
end
|
||||
|
||||
it 'deletes the users redirect_to_wizard if present' do
|
||||
user.custom_fields['redirect_to_wizard'] = @template["id"]
|
||||
it "deletes the users redirect_to_wizard if present" do
|
||||
user.custom_fields["redirect_to_wizard"] = @template["id"]
|
||||
user.save_custom_fields(true)
|
||||
@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(user.reload.redirect_to_wizard).to eq(nil)
|
||||
end
|
||||
|
@ -78,22 +76,25 @@ describe CustomWizard::WizardController do
|
|||
@wizard = CustomWizard::Wizard.create(@template["id"], user)
|
||||
CustomWizard::Submission.new(@wizard, step_1_field_1: "Hello World").save
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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",
|
||||
params: {
|
||||
fields: {
|
||||
step_1_field_1: "Text input"
|
||||
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
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::BasicWizardSerializer do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
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)
|
||||
json = CustomWizard::BasicWizardSerializer.new(
|
||||
json =
|
||||
CustomWizard::BasicWizardSerializer.new(
|
||||
CustomWizard::Builder.new("super_mega_fun_wizard", user).build,
|
||||
scope: Guardian.new(user)
|
||||
scope: Guardian.new(user),
|
||||
).as_json
|
||||
expect(json[:basic_wizard][:id]).to eq("super_mega_fun_wizard")
|
||||
expect(json[:basic_wizard][:name]).to eq("Super Mega Fun Wizard")
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::CustomFieldSerializer do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
|
||||
|
||||
it 'should return custom field attributes' do
|
||||
custom_field_json['custom_fields'].each do |field_json|
|
||||
it "should return custom field attributes" do
|
||||
custom_field_json["custom_fields"].each do |field_json|
|
||||
CustomWizard::CustomField.new(nil, field_json).save
|
||||
end
|
||||
|
||||
json = CustomWizard::CustomFieldSerializer.new(
|
||||
json =
|
||||
CustomWizard::CustomFieldSerializer.new(
|
||||
CustomWizard::CustomField.find_by_name("topic_field_1"),
|
||||
scope: Guardian.new(user),
|
||||
root: false
|
||||
root: false,
|
||||
).as_json
|
||||
expect(json[:name]).to eq("topic_field_1")
|
||||
expect(json[:klass]).to eq("topic")
|
||||
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
|
||||
|
|
|
@ -1,19 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe CustomWizard::LogSerializer do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user)
|
||||
|
||||
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('second-test-wizard', 'perform_second_action', 'second_test_user', 'Second log message')
|
||||
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(
|
||||
"second-test-wizard",
|
||||
"perform_second_action",
|
||||
"second_test_user",
|
||||
"Second log message",
|
||||
)
|
||||
|
||||
json_array = ActiveModel::ArraySerializer.new(
|
||||
json_array =
|
||||
ActiveModel::ArraySerializer.new(
|
||||
CustomWizard::Log.list(0).logs,
|
||||
each_serializer: CustomWizard::LogSerializer
|
||||
each_serializer: CustomWizard::LogSerializer,
|
||||
).as_json
|
||||
expect(json_array.length).to eq(2)
|
||||
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")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../plugin_helper'
|
||||
require_relative "../../plugin_helper"
|
||||
|
||||
describe CustomWizard::SubmissionSerializer do
|
||||
fab!(:user1) { Fabricate(:user) }
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
|
||||
let(:template_json) {
|
||||
JSON.parse(File.open(
|
||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
||||
).read)
|
||||
}
|
||||
let(:template_json) do
|
||||
JSON.parse(
|
||||
File.open("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json").read,
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
CustomWizard::Template.save(template_json, skip_jobs: true)
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
it 'should return submission attributes' do
|
||||
it "should return submission attributes" do
|
||||
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(
|
||||
list.submissions,
|
||||
each_serializer: described_class
|
||||
).as_json
|
||||
json_array =
|
||||
ActiveModel::ArraySerializer.new(list.submissions, each_serializer: described_class).as_json
|
||||
|
||||
expect(json_array.length).to eq(2)
|
||||
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
|
||||
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(
|
||||
list.submissions,
|
||||
each_serializer: described_class
|
||||
).as_json
|
||||
json_array =
|
||||
ActiveModel::ArraySerializer.new(list.submissions, each_serializer: described_class).as_json
|
||||
|
||||
expect(json_array.length).to eq(2)
|
||||
expect(json_array[0][:fields].as_json).to eq({
|
||||
"step_1_field_1": {
|
||||
"value": "I am user2 submission",
|
||||
"type": "text",
|
||||
"label": "Text"
|
||||
}
|
||||
}.as_json)
|
||||
expect(json_array[0][:fields].as_json).to eq(
|
||||
{ step_1_field_1: { value: "I am user2 submission", type: "text", label: "Text" } }.as_json,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden …
In neuem Issue referenzieren