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

Apply rubcop and get tests pass (#76)

Dieser Commit ist enthalten in:
Angus McLeod 2021-03-11 17:30:15 +11:00 committet von GitHub
Ursprung 065bc17929
Commit 4edb40e526
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
91 geänderte Dateien mit 1070 neuen und 1006 gelöschten Zeilen

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
CustomWizard::Engine.routes.draw do CustomWizard::Engine.routes.draw do
get ':wizard_id' => 'wizard#index' get ':wizard_id' => 'wizard#index'
put ':wizard_id/skip' => 'wizard#skip' put ':wizard_id/skip' => 'wizard#skip'
@ -13,21 +14,21 @@ Discourse::Application.routes.append do
scope module: 'custom_wizard', constraints: AdminConstraint.new do scope module: 'custom_wizard', constraints: AdminConstraint.new do
get 'admin/wizards' => 'admin#index' get 'admin/wizards' => 'admin#index'
get 'admin/wizards/wizard' => 'admin_wizard#index' get 'admin/wizards/wizard' => 'admin_wizard#index'
get 'admin/wizards/wizard/create' => 'admin#index' get 'admin/wizards/wizard/create' => 'admin#index'
get 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#show' get 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#show'
put 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#save' put 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#save'
delete 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#remove' delete 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#remove'
get 'admin/wizards/custom-fields' => 'admin_custom_fields#index' get 'admin/wizards/custom-fields' => 'admin_custom_fields#index'
put 'admin/wizards/custom-fields' => 'admin_custom_fields#update' put 'admin/wizards/custom-fields' => 'admin_custom_fields#update'
delete 'admin/wizards/custom-fields/:name' => 'admin_custom_fields#destroy' delete 'admin/wizards/custom-fields/:name' => 'admin_custom_fields#destroy'
get 'admin/wizards/submissions' => 'admin_submissions#index' get 'admin/wizards/submissions' => 'admin_submissions#index'
get 'admin/wizards/submissions/:wizard_id' => 'admin_submissions#show' get 'admin/wizards/submissions/:wizard_id' => 'admin_submissions#show'
get 'admin/wizards/submissions/:wizard_id/download' => 'admin_submissions#download' get 'admin/wizards/submissions/:wizard_id/download' => 'admin_submissions#download'
get 'admin/wizards/api' => 'admin_api#list' get 'admin/wizards/api' => 'admin_api#list'
get 'admin/wizards/api/:name' => 'admin_api#find' get 'admin/wizards/api/:name' => 'admin_api#find'
put 'admin/wizards/api/:name' => 'admin_api#save' put 'admin/wizards/api/:name' => 'admin_api#save'
@ -35,12 +36,12 @@ Discourse::Application.routes.append do
delete 'admin/wizards/api/:name/logs' => 'admin_api#clearlogs' delete 'admin/wizards/api/:name/logs' => 'admin_api#clearlogs'
get 'admin/wizards/api/:name/redirect' => 'admin_api#redirect' get 'admin/wizards/api/:name/redirect' => 'admin_api#redirect'
get 'admin/wizards/api/:name/authorize' => 'admin_api#authorize' get 'admin/wizards/api/:name/authorize' => 'admin_api#authorize'
get 'admin/wizards/logs' => 'admin_logs#index' get 'admin/wizards/logs' => 'admin_logs#index'
get 'admin/wizards/manager' => 'admin_manager#index' get 'admin/wizards/manager' => 'admin_manager#index'
get 'admin/wizards/manager/export' => 'admin_manager#export' get 'admin/wizards/manager/export' => 'admin_manager#export'
post 'admin/wizards/manager/import' => 'admin_manager#import' post 'admin/wizards/manager/import' => 'admin_manager#import'
delete 'admin/wizards/manager/destroy' => 'admin_manager#destroy' delete 'admin/wizards/manager/destroy' => 'admin_manager#destroy'
end end
end end

Datei anzeigen

@ -1,22 +1,23 @@
# frozen_string_literal: true
class CustomWizard::AdminController < ::Admin::AdminController class CustomWizard::AdminController < ::Admin::AdminController
before_action :ensure_admin before_action :ensure_admin
def index def index
end end
private private
def find_wizard def find_wizard
params.require(:wizard_id) params.require(:wizard_id)
@wizard = CustomWizard::Wizard.create(params[:wizard_id].underscore) @wizard = CustomWizard::Wizard.create(params[:wizard_id].underscore)
raise Discourse::InvalidParameters.new(:wizard_id) unless @wizard raise Discourse::InvalidParameters.new(:wizard_id) unless @wizard
end end
def custom_field_list def custom_field_list
serialize_data(CustomWizard::CustomField.list, CustomWizard::CustomFieldSerializer) serialize_data(CustomWizard::CustomField.list, CustomWizard::CustomFieldSerializer)
end end
def render_error(message) def render_error(message)
render json: failed_json.merge(error: message) render json: failed_json.merge(error: message)
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::AdminApiController < CustomWizard::AdminController class CustomWizard::AdminApiController < CustomWizard::AdminController
skip_before_action :check_xhr, only: [:redirect] skip_before_action :check_xhr, only: [:redirect]
@ -85,7 +86,7 @@ class CustomWizard::AdminApiController < CustomWizard::AdminController
CustomWizard::Api::Authorization.set(params[:name], code: params[:code]) CustomWizard::Api::Authorization.set(params[:name], code: params[:code])
CustomWizard::Api::Authorization.get_token(params[:name]) CustomWizard::Api::Authorization.get_token(params[:name])
return redirect_to path('/admin/wizards/apis/' + params[:name]) redirect_to path('/admin/wizards/apis/' + params[:name])
end end
private private

Datei anzeigen

@ -1,26 +1,27 @@
# frozen_string_literal: true
class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
def index def index
render_json_dump(custom_field_list) render_json_dump(custom_field_list)
end end
def update def update
errors = [] errors = []
field_id = nil field_id = nil
field_data = {} field_data = {}
if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i) if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i)
CustomWizard::CustomField::ATTRS.each do |attr| CustomWizard::CustomField::ATTRS.each do |attr|
field_data[attr] = saved_field.send(attr) field_data[attr] = saved_field.send(attr)
end end
field_id = saved_field.id field_id = saved_field.id
end end
CustomWizard::CustomField::ATTRS.each do |attr| CustomWizard::CustomField::ATTRS.each do |attr|
field_data[attr] = field_params[attr] field_data[attr] = field_params[attr]
end end
field = CustomWizard::CustomField.new(field_id, field_data) field = CustomWizard::CustomField.new(field_id, field_data)
PluginStoreRow.transaction do PluginStoreRow.transaction do
unless field.save unless field.save
field_errors = field.errors.any? ? field_errors = field.errors.any? ?
@ -30,26 +31,26 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
raise ActiveRecord::Rollback.new raise ActiveRecord::Rollback.new
end end
end end
if errors.any? if errors.any?
render json: failed_json.merge(messages: errors) render json: failed_json.merge(messages: errors)
else else
render json: success_json render json: success_json
end end
end end
def destroy def destroy
params.require(:name) params.require(:name)
if CustomWizard::CustomField.destroy(params[:name]) if CustomWizard::CustomField.destroy(params[:name])
render json: success_json render json: success_json
else else
render json: failed_json render json: failed_json
end end
end end
private private
def field_params def field_params
params.required(:custom_field) params.required(:custom_field)
.permit( .permit(
@ -60,4 +61,4 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
serializers: [] serializers: []
) )
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::AdminLogsController < CustomWizard::AdminController class CustomWizard::AdminLogsController < CustomWizard::AdminController
def index def index
render_serialized( render_serialized(
@ -5,4 +6,4 @@ class CustomWizard::AdminLogsController < CustomWizard::AdminController
CustomWizard::LogSerializer CustomWizard::LogSerializer
) )
end end
end end

Datei anzeigen

@ -1,22 +1,23 @@
# frozen_string_literal: true
class CustomWizard::AdminManagerController < CustomWizard::AdminController class CustomWizard::AdminManagerController < CustomWizard::AdminController
skip_before_action :check_xhr, only: [:export] skip_before_action :check_xhr, only: [:export]
before_action :get_wizard_ids, except: [:import] before_action :get_wizard_ids, except: [:import]
def export def export
templates = [] templates = []
@wizard_ids.each do |wizard_id| @wizard_ids.each do |wizard_id|
if template = CustomWizard::Template.find(wizard_id) if template = CustomWizard::Template.find(wizard_id)
templates.push(template) templates.push(template)
end end
end end
if templates.empty? if templates.empty?
return render_error(I18n.t('wizard.export.error.invalid_wizards')) return render_error(I18n.t('wizard.export.error.invalid_wizards'))
end end
basename = SiteSetting.title.parameterize || 'discourse' basename = SiteSetting.title.parameterize || 'discourse'
time = Time.now.to_i time = Time.now.to_i
filename = "#{basename}-wizards-#{time}.json" filename = "#{basename}-wizards-#{time}.json"
send_data templates.to_json, send_data templates.to_json,
@ -27,31 +28,31 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
def import def import
file = File.read(params['file'].tempfile) file = File.read(params['file'].tempfile)
if file.nil? if file.nil?
return render_error(I18n.t('wizard.export.error.no_file')) return render_error(I18n.t('wizard.export.error.no_file'))
end end
file_size = file.size file_size = file.size
max_file_size = 512 * 1024 max_file_size = 512 * 1024
if max_file_size < file_size if max_file_size < file_size
return render_error(I18n.t('wizard.import.error.file_large')) return render_error(I18n.t('wizard.import.error.file_large'))
end end
begin begin
template_json = JSON.parse file template_json = JSON.parse file
rescue JSON::ParserError rescue JSON::ParserError
return render_error(I18n.t('wizard.import.error.invalid_json')) return render_error(I18n.t('wizard.import.error.invalid_json'))
end end
imported = [] imported = []
failures = [] failures = []
template_json.each do |json| template_json.each do |json|
template = CustomWizard::Template.new(json) template = CustomWizard::Template.new(json)
template.save(skip_jobs: true, create: true) template.save(skip_jobs: true, create: true)
if template.errors.any? if template.errors.any?
failures.push( failures.push(
id: json['id'], id: json['id'],
@ -70,14 +71,14 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
failures: failures failures: failures
) )
end end
def destroy def destroy
destroyed = [] destroyed = []
failures = [] failures = []
@wizard_ids.each do |wizard_id| @wizard_ids.each do |wizard_id|
template = CustomWizard::Template.find(wizard_id) template = CustomWizard::Template.find(wizard_id)
if template && CustomWizard::Template.remove(wizard_id) if template && CustomWizard::Template.remove(wizard_id)
destroyed.push( destroyed.push(
id: wizard_id, id: wizard_id,
@ -90,22 +91,22 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
) )
end end
end end
render json: success_json.merge( render json: success_json.merge(
destroyed: destroyed, destroyed: destroyed,
failures: failures failures: failures
) )
end end
private private
def get_wizard_ids def get_wizard_ids
if params['wizard_ids'].blank? if params['wizard_ids'].blank?
return render_error(I18n.t('wizard.export.error.select_one')) return render_error(I18n.t('wizard.export.error.select_one'))
end end
wizard_ids = [] wizard_ids = []
params['wizard_ids'].each do |wizard_id| params['wizard_ids'].each do |wizard_id|
begin begin
wizard_ids.push(wizard_id.underscore) wizard_ids.push(wizard_id.underscore)
@ -113,11 +114,11 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController
# #
end end
end end
if wizard_ids.empty? if wizard_ids.empty?
return render_error(I18n.t('wizard.export.error.invalid_wizards')) return render_error(I18n.t('wizard.export.error.invalid_wizards'))
end end
@wizard_ids = wizard_ids @wizard_ids = wizard_ids
end end
end end

Datei anzeigen

@ -1,45 +1,46 @@
# frozen_string_literal: true
class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
skip_before_action :preload_json, :check_xhr, only: [:download] skip_before_action :preload_json, :check_xhr, only: [:download]
before_action :find_wizard, except: [:index] before_action :find_wizard, except: [:index]
def index def index
render json: ActiveModel::ArraySerializer.new( render json: ActiveModel::ArraySerializer.new(
CustomWizard::Wizard.list(current_user), CustomWizard::Wizard.list(current_user),
each_serializer: CustomWizard::BasicWizardSerializer each_serializer: CustomWizard::BasicWizardSerializer
) )
end end
def show def show
render_json_dump( render_json_dump(
wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false), wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false),
submissions: build_submissions.as_json submissions: build_submissions.as_json
) )
end end
def download def download
send_data build_submissions.to_json, send_data build_submissions.to_json,
filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json", filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json",
content_type: "application/json", content_type: "application/json",
disposition: "attachment" disposition: "attachment"
end end
private private
def build_submissions def build_submissions
PluginStoreRow.where(plugin_name: "#{@wizard.id}_submissions") PluginStoreRow.where(plugin_name: "#{@wizard.id}_submissions")
.order('id DESC') .order('id DESC')
.map do |row| .map do |row|
value = ::JSON.parse(row.value) value = ::JSON.parse(row.value)
if user = User.find_by(id: row.key) if user = User.find_by(id: row.key)
username = user.username username = user.username
else else
username = I18n.t('admin.wizard.submissions.no_user', id: row.key) username = I18n.t('admin.wizard.submissions.no_user', id: row.key)
end end
value.map do |v| value.map do |v|
{ username: username }.merge!(v.except("redirect_to")) { username: username }.merge!(v.except("redirect_to"))
end end
end.flatten end.flatten
end end
end end

Datei anzeigen

@ -1,6 +1,7 @@
# frozen_string_literal: true
class CustomWizard::AdminWizardController < CustomWizard::AdminController class CustomWizard::AdminWizardController < CustomWizard::AdminController
before_action :find_wizard, only: [:show, :remove] before_action :find_wizard, only: [:show, :remove]
def index def index
render_json_dump( render_json_dump(
wizard_list: ActiveModel::ArraySerializer.new( wizard_list: ActiveModel::ArraySerializer.new(
@ -12,17 +13,17 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
custom_fields: custom_field_list custom_fields: custom_field_list
) )
end end
def show def show
params.require(:wizard_id) params.require(:wizard_id)
if data = CustomWizard::Template.find(params[:wizard_id].underscore) if data = CustomWizard::Template.find(params[:wizard_id].underscore)
render json: data.as_json render json: data.as_json
else else
render json: { none: true } render json: { none: true }
end end
end end
def remove def remove
if CustomWizard::Template.remove(@wizard.id) if CustomWizard::Template.remove(@wizard.id)
render json: success_json render json: success_json
@ -34,16 +35,16 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
def save def save
template = CustomWizard::Template.new(save_wizard_params.to_h) template = CustomWizard::Template.new(save_wizard_params.to_h)
wizard_id = template.save(create: params[:create]) wizard_id = template.save(create: params[:create])
if template.errors.any? if template.errors.any?
render json: failed_json.merge(errors: result.errors.full_messages) render json: failed_json.merge(errors: result.errors.full_messages)
else else
render json: success_json.merge(wizard_id: wizard_id) render json: success_json.merge(wizard_id: wizard_id)
end end
end end
private private
def mapped_params def mapped_params
[ [
:type, :type,

Datei anzeigen

@ -6,9 +6,9 @@ class CustomWizard::RealtimeValidationsController < ::ApplicationController
result = klass_str.constantize.new(current_user).perform(validation_params) result = klass_str.constantize.new(current_user).perform(validation_params)
render_serialized(result.items, "#{klass_str}Serializer".constantize, result.serializer_opts) render_serialized(result.items, "#{klass_str}Serializer".constantize, result.serializer_opts)
end end
private private
def validation_params def validation_params
params.require(:type) params.require(:type)
settings = ::CustomWizard::RealtimeValidation.types[params[:type].to_sym] settings = ::CustomWizard::RealtimeValidation.types[params[:type].to_sym]

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::StepsController < ::ApplicationController class CustomWizard::StepsController < ::ApplicationController
before_action :ensure_logged_in before_action :ensure_logged_in
before_action :ensure_can_update before_action :ensure_can_update
@ -5,14 +6,14 @@ class CustomWizard::StepsController < ::ApplicationController
def update def update
params.require(:step_id) params.require(:step_id)
params.require(:wizard_id) params.require(:wizard_id)
wizard = @builder.build wizard = @builder.build
step = wizard.steps.select { |s| s.id == update_params[:step_id] }.first step = wizard.steps.select { |s| s.id == update_params[:step_id] }.first
raise Discourse::InvalidParameters.new(:step_id) if !step raise Discourse::InvalidParameters.new(:step_id) if !step
update = update_params.to_h update = update_params.to_h
update[:fields] = {} update[:fields] = {}
if params[:fields] if params[:fields]
field_ids = step.fields.map(&:id) field_ids = step.fields.map(&:id)
@ -20,15 +21,15 @@ class CustomWizard::StepsController < ::ApplicationController
update[:fields][k] = v if field_ids.include? k update[:fields][k] = v if field_ids.include? k
end end
end end
updater = wizard.create_updater(update[:step_id], update[:fields]) updater = wizard.create_updater(update[:step_id], update[:fields])
updater.update updater.update
if updater.success? if updater.success?
result = success_json result = success_json
result.merge!(updater.result) if updater.result result.merge!(updater.result) if updater.result
result[:refresh_required] = true if updater.refresh_required? result[:refresh_required] = true if updater.refresh_required?
render json: result render json: result
else else
errors = [] errors = []
@ -38,24 +39,24 @@ class CustomWizard::StepsController < ::ApplicationController
render json: { errors: errors }, status: 422 render json: { errors: errors }, status: 422
end end
end end
private private
def ensure_can_update def ensure_can_update
@builder = CustomWizard::Builder.new( @builder = CustomWizard::Builder.new(
update_params[:wizard_id].underscore, update_params[:wizard_id].underscore,
current_user current_user
) )
if @builder.nil? if @builder.nil?
raise Discourse::InvalidParameters.new(:wizard_id) raise Discourse::InvalidParameters.new(:wizard_id)
end end
if !@builder.wizard || !@builder.wizard.can_access? if !@builder.wizard || !@builder.wizard.can_access?
raise Discourse::InvalidAccess.new raise Discourse::InvalidAccess.new
end end
end end
def update_params def update_params
params.permit(:wizard_id, :step_id) params.permit(:wizard_id, :step_id)
end end

Datei anzeigen

@ -1,7 +1,8 @@
# frozen_string_literal: true
class CustomWizard::WizardController < ::ApplicationController class CustomWizard::WizardController < ::ApplicationController
prepend_view_path(Rails.root.join('plugins', 'discourse-custom-wizard', 'views')) prepend_view_path(Rails.root.join('plugins', 'discourse-custom-wizard', 'views'))
layout 'wizard' layout 'wizard'
before_action :ensure_plugin_enabled before_action :ensure_plugin_enabled
helper_method :wizard_page_title helper_method :wizard_page_title
helper_method :wizard_theme_ids helper_method :wizard_theme_ids
@ -22,12 +23,12 @@ class CustomWizard::WizardController < ::ApplicationController
respond_to do |format| respond_to do |format|
format.json do format.json do
builder = CustomWizard::Builder.new(params[:wizard_id].underscore, current_user) builder = CustomWizard::Builder.new(params[:wizard_id].underscore, current_user)
if builder.wizard.present? if builder.wizard.present?
builder_opts = {} builder_opts = {}
builder_opts[:reset] = params[:reset] builder_opts[:reset] = params[:reset]
built_wizard = builder.build(builder_opts, params) built_wizard = builder.build(builder_opts, params)
render_serialized(built_wizard, ::CustomWizard::WizardSerializer, root: false) render_serialized(built_wizard, ::CustomWizard::WizardSerializer, root: false)
else else
render json: { error: I18n.t('wizard.none') } render json: { error: I18n.t('wizard.none') }
@ -39,14 +40,14 @@ class CustomWizard::WizardController < ::ApplicationController
def skip def skip
params.require(:wizard_id) params.require(:wizard_id)
if wizard.required && !wizard.completed? && wizard.permitted? if wizard.required && !wizard.completed? && wizard.permitted?
return render json: { error: I18n.t('wizard.no_skip') } return render json: { error: I18n.t('wizard.no_skip') }
end end
result = success_json result = success_json
user = current_user user = current_user
if user if user
submission = wizard.current_submission submission = wizard.current_submission
if submission && submission['redirect_to'] if submission && submission['redirect_to']
@ -61,9 +62,9 @@ class CustomWizard::WizardController < ::ApplicationController
render json: result render json: result
end end
private private
def ensure_plugin_enabled def ensure_plugin_enabled
unless SiteSetting.custom_wizard_enabled unless SiteSetting.custom_wizard_enabled
redirect_to path("/") redirect_to path("/")

Datei anzeigen

@ -1,27 +1,28 @@
# frozen_string_literal: true
class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0] class UpdateWatchCategoriesAction < ActiveRecord::Migration[6.0]
def change def change
watch_category_wizards = PluginStoreRow.where(" watch_category_wizards = PluginStoreRow.where("
plugin_name = 'custom_wizard' AND plugin_name = 'custom_wizard' AND
value::jsonb -> 'actions' @> '[{ \"type\" : \"watch_categories\" }]'::jsonb value::jsonb -> 'actions' @> '[{ \"type\" : \"watch_categories\" }]'::jsonb
") ")
if watch_category_wizards.exists? if watch_category_wizards.exists?
watch_category_wizards.each do |row| watch_category_wizards.each do |row|
begin begin
wizard_json = JSON.parse(row.value) wizard_json = JSON.parse(row.value)
rescue TypeError, JSON::ParserError rescue TypeError, JSON::ParserError
next next
end end
wizard_json['actions'].each do |a| wizard_json['actions'].each do |a|
if a['type'] === "watch_categories" && a['wizard_user'] == nil if a['type'] === "watch_categories" && a['wizard_user'] == nil
a['wizard_user'] = true a['wizard_user'] = true
end end
end end
row.value = wizard_json.to_json row.value = wizard_json.to_json
row.save row.save
end end
end end
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module CustomWizardCustomFieldPreloader module CustomWizardCustomFieldPreloader
def preload_custom_fields(objects, fields) def preload_custom_fields(objects, fields)
if objects.present? && cw_fields_enabled? if objects.present? && cw_fields_enabled?
@ -10,12 +11,12 @@ module CustomWizardCustomFieldPreloader
end end
super(objects, fields) super(objects, fields)
end end
def cw_fields_enabled? def cw_fields_enabled?
SiteSetting.custom_wizard_enabled && CustomWizard::CustomField.enabled? SiteSetting.custom_wizard_enabled && CustomWizard::CustomField.enabled?
end end
def cw_fields def cw_fields
CustomWizard::CustomField.list_by(:klass, @cw_klass) CustomWizard::CustomField.list_by(:klass, @cw_klass)
end end
end end

Datei anzeigen

@ -1,10 +1,11 @@
# frozen_string_literal: true
module CustomWizardCustomFieldSerializer module CustomWizardCustomFieldSerializer
def attributes(*args) def attributes(*args)
hash = super hash = super
if cw_fields_enabled? if cw_fields_enabled?
@cw_klass = get_cw_class @cw_klass = get_cw_class
if cw_fields.any? if cw_fields.any?
cw_fields.each do |field| cw_fields.each do |field|
if @cw_klass == "topic_view" if @cw_klass == "topic_view"
@ -15,12 +16,12 @@ module CustomWizardCustomFieldSerializer
end end
end end
end end
hash hash
end end
private private
def cw_fields_enabled? def cw_fields_enabled?
SiteSetting.custom_wizard_enabled && CustomWizard::CustomField.enabled? SiteSetting.custom_wizard_enabled && CustomWizard::CustomField.enabled?
end end
@ -28,7 +29,7 @@ module CustomWizardCustomFieldSerializer
def cw_fields def cw_fields
CustomWizard::CustomField.list_by(:serializers, @cw_klass) CustomWizard::CustomField.list_by(:serializers, @cw_klass)
end end
def get_cw_class def get_cw_class
self.class.ancestors.map do |klass| self.class.ancestors.map do |klass|
klass.to_s.underscore.gsub("_serializer", "") klass.to_s.underscore.gsub("_serializer", "")
@ -36,4 +37,4 @@ module CustomWizardCustomFieldSerializer
CustomWizard::CustomField.serializers.include?(klass) CustomWizard::CustomField.serializers.include?(klass)
end.first end.first
end end
end end

Datei anzeigen

@ -1,10 +1,11 @@
# frozen_string_literal: true
module ExtraLocalesControllerCustomWizard module ExtraLocalesControllerCustomWizard
private def valid_bundle?(bundle) private def valid_bundle?(bundle)
super || begin super || begin
return false unless bundle =~ /wizard/ && request.referer =~ /\/w\// return false unless bundle =~ /wizard/ && request.referer =~ /\/w\//
path = URI(request.referer).path path = URI(request.referer).path
wizard_id = path.split('/w/').last wizard_id = path.split('/w/').last
CustomWizard::Template.exists?(wizard_id.underscore) CustomWizard::Template.exists?(wizard_id.underscore)
end end
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module InvitesControllerCustomWizard module InvitesControllerCustomWizard
def path(url) def path(url)
if ::Wizard.user_requires_completion?(@user) if ::Wizard.user_requires_completion?(@user)
@ -15,4 +16,4 @@ module InvitesControllerCustomWizard
super super
@user = user @user = user
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module CustomWizardUsersController module CustomWizardUsersController
def account_created def account_created
if current_user.present? && if current_user.present? &&
@ -6,4 +7,4 @@ module CustomWizardUsersController
end end
super super
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module CustomWizardFieldExtension module CustomWizardFieldExtension
attr_reader :raw, attr_reader :raw,
:label, :label,
@ -14,7 +15,7 @@ module CustomWizardFieldExtension
:property, :property,
:content, :content,
:number :number
def initialize(attrs) def initialize(attrs)
super super
@raw = attrs || {} @raw = attrs || {}
@ -36,4 +37,4 @@ module CustomWizardFieldExtension
def label def label
@label ||= PrettyText.cook(@raw[:label]) @label ||= PrettyText.cook(@raw[:label])
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module CustomWizardStepExtension module CustomWizardStepExtension
attr_accessor :title, :description, :key, :permitted, :permitted_message attr_accessor :title, :description, :key, :permitted, :permitted_message
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module Jobs module Jobs
class ClearAfterTimeWizard < ::Jobs::Base class ClearAfterTimeWizard < ::Jobs::Base
sidekiq_options queue: 'critical' sidekiq_options queue: 'critical'

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
module Jobs module Jobs
class RefreshApiAccessToken < ::Jobs::Base class RefreshApiAccessToken < ::Jobs::Base
def execute(args) def execute(args)

Datei anzeigen

@ -1,9 +1,10 @@
# frozen_string_literal: true
module Jobs module Jobs
class SetAfterTimeWizard < ::Jobs::Base class SetAfterTimeWizard < ::Jobs::Base
def execute(args) def execute(args)
if SiteSetting.custom_wizard_enabled if SiteSetting.custom_wizard_enabled
wizard = CustomWizard::Wizard.create(args[:wizard_id]) wizard = CustomWizard::Wizard.create(args[:wizard_id])
if wizard && wizard.after_time if wizard && wizard.after_time
user_ids = [] user_ids = []

Datei anzeigen

@ -1,10 +1,11 @@
# frozen_string_literal: true
class CustomWizard::Action class CustomWizard::Action
attr_accessor :data, attr_accessor :data,
:action, :action,
:user, :user,
:guardian, :guardian,
:result :result
def initialize(params) def initialize(params)
@wizard = params[:wizard] @wizard = params[:wizard]
@action = params[:action] @action = params[:action]
@ -14,41 +15,41 @@ class CustomWizard::Action
@log = [] @log = []
@result = CustomWizard::ActionResult.new @result = CustomWizard::ActionResult.new
end end
def perform def perform
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
self.send(action['type'].to_sym) self.send(action['type'].to_sym)
end end
if creates_post? && @result.success? if creates_post? && @result.success?
@result.handler.enqueue_jobs @result.handler.enqueue_jobs
end end
if @result.success? && @result.output.present? if @result.success? && @result.output.present?
data[action['id']] = @result.output data[action['id']] = @result.output
end end
save_log save_log
end end
def mapper def mapper
@mapper ||= CustomWizard::Mapper.new(user: user, data: data) @mapper ||= CustomWizard::Mapper.new(user: user, data: data)
end end
def create_topic def create_topic
params = basic_topic_params.merge(public_topic_params) params = basic_topic_params.merge(public_topic_params)
if params[:title].present? && params[:raw].present? if params[:title].present? && params[:raw].present?
creator = PostCreator.new(user, params) creator = PostCreator.new(user, params)
post = creator.create post = creator.create
if creator.errors.present? if creator.errors.present?
messages = creator.errors.full_messages.join(" ") messages = creator.errors.full_messages.join(" ")
log_error("failed to create", messages) log_error("failed to create", messages)
elsif action['skip_redirect'].blank? elsif action['skip_redirect'].blank?
data['redirect_on_complete'] = post.topic.url data['redirect_on_complete'] = post.topic.url
end end
if creator.errors.blank? if creator.errors.blank?
log_success("created topic", "id: #{post.topic.id}") log_success("created topic", "id: #{post.topic.id}")
result.handler = creator result.handler = creator
@ -58,7 +59,7 @@ class CustomWizard::Action
log_error("invalid topic params", "title: #{params[:title]}; post: #{params[:raw]}") log_error("invalid topic params", "title: #{params[:title]}; post: #{params[:raw]}")
end end
end end
def send_message def send_message
if action['required'].present? if action['required'].present?
@ -67,27 +68,27 @@ class CustomWizard::Action
data: data, data: data,
user: user user: user
).perform ).perform
if required.blank? if required.blank?
log_error("required input not present") log_error("required input not present")
return return
end end
end end
params = basic_topic_params params = basic_topic_params
targets = CustomWizard::Mapper.new( targets = CustomWizard::Mapper.new(
inputs: action['recipient'], inputs: action['recipient'],
data: data, data: data,
user: user, user: user,
multiple: true multiple: true
).perform ).perform
if targets.blank? if targets.blank?
log_error("no recipients", "send_message has no recipients") log_error("no recipients", "send_message has no recipients")
return return
end end
targets.each do |target| targets.each do |target|
if Group.find_by(name: target) if Group.find_by(name: target)
params[:target_group_names] = target params[:target_group_names] = target
@ -97,14 +98,14 @@ class CustomWizard::Action
# #
end end
end end
if params[:title].present? && if params[:title].present? &&
params[:raw].present? && params[:raw].present? &&
(params[:target_usernames].present? || (params[:target_usernames].present? ||
params[:target_group_names].present?) params[:target_group_names].present?)
params[:archetype] = Archetype.private_message params[:archetype] = Archetype.private_message
creator = PostCreator.new(user, params) creator = PostCreator.new(user, params)
post = creator.create post = creator.create
@ -114,7 +115,7 @@ class CustomWizard::Action
elsif action['skip_redirect'].blank? elsif action['skip_redirect'].blank?
data['redirect_on_complete'] = post.topic.url data['redirect_on_complete'] = post.topic.url
end end
if creator.errors.blank? if creator.errors.blank?
log_success("created message", "id: #{post.topic.id}") log_success("created message", "id: #{post.topic.id}")
result.handler = creator result.handler = creator
@ -130,7 +131,7 @@ class CustomWizard::Action
def update_profile def update_profile
params = {} params = {}
if (profile_updates = action['profile_updates']) if (profile_updates = action['profile_updates'])
profile_updates.first[:pairs].each do |pair| profile_updates.first[:pairs].each do |pair|
if allowed_profile_field?(pair['key']) if allowed_profile_field?(pair['key'])
@ -142,7 +143,7 @@ class CustomWizard::Action
), ),
pair['key'] pair['key']
) )
if user_field?(pair['key']) if user_field?(pair['key'])
params[:custom_fields] ||= {} params[:custom_fields] ||= {}
params[:custom_fields][key] = value params[:custom_fields][key] = value
@ -152,16 +153,16 @@ class CustomWizard::Action
end end
end end
end end
params = add_custom_fields(params) params = add_custom_fields(params)
if params.present? if params.present?
result = UserUpdater.new(Discourse.system_user, user).update(params) result = UserUpdater.new(Discourse.system_user, user).update(params)
if params[:avatar].present? if params[:avatar].present?
result = update_avatar(params[:avatar]) result = update_avatar(params[:avatar])
end end
if result if result
log_success("updated profile fields", "fields: #{params.keys.map(&:to_s).join(',')}") log_success("updated profile fields", "fields: #{params.keys.map(&:to_s).join(',')}")
else else
@ -178,7 +179,7 @@ class CustomWizard::Action
data: data, data: data,
user: user user: user
).perform ).perform
watched_categories = [*watched_categories].map(&:to_i) watched_categories = [*watched_categories].map(&:to_i)
notification_level = action['notification_level'] notification_level = action['notification_level']
@ -193,23 +194,23 @@ class CustomWizard::Action
data: data, data: data,
user: user user: user
).perform ).perform
users = [] users = []
if action['usernames'] if action['usernames']
mapped_users = CustomWizard::Mapper.new( mapped_users = CustomWizard::Mapper.new(
inputs: action['usernames'], inputs: action['usernames'],
data: data, data: data,
user: user user: user
).perform ).perform
if mapped_users.present? if mapped_users.present?
mapped_users = mapped_users.split(',') mapped_users = mapped_users.split(',')
.map { |username| User.find_by(username: username) } .map { |username| User.find_by(username: username) }
users.push(*mapped_users) users.push(*mapped_users)
end end
end end
if ActiveRecord::Type::Boolean.new.cast(action['wizard_user']) if ActiveRecord::Type::Boolean.new.cast(action['wizard_user'])
users.push(user) users.push(user)
end end
@ -217,26 +218,26 @@ class CustomWizard::Action
category_ids = Category.all.pluck(:id) category_ids = Category.all.pluck(:id)
set_level = CategoryUser.notification_levels[notification_level.to_sym] set_level = CategoryUser.notification_levels[notification_level.to_sym]
mute_level = CategoryUser.notification_levels[:muted] mute_level = CategoryUser.notification_levels[:muted]
users.each do |user| users.each do |user|
category_ids.each do |category_id| category_ids.each do |category_id|
new_level = nil new_level = nil
if watched_categories.include?(category_id) && set_level != nil if watched_categories.include?(category_id) && set_level != nil
new_level = set_level new_level = set_level
elsif mute_remainder elsif mute_remainder
new_level = mute_level new_level = mute_level
end end
if new_level if new_level
CategoryUser.set_notification_level_for_category(user, new_level, category_id) CategoryUser.set_notification_level_for_category(user, new_level, category_id)
end end
end end
if watched_categories.any? if watched_categories.any?
log_success("#{user.username} notifications for #{watched_categories} set to #{set_level}") log_success("#{user.username} notifications for #{watched_categories} set to #{set_level}")
end end
if mute_remainder if mute_remainder
log_success("#{user.username} notifications for all other categories muted") log_success("#{user.username} notifications for all other categories muted")
end end
@ -264,29 +265,29 @@ class CustomWizard::Action
log_success("api request succeeded", "result: #{result}") log_success("api request succeeded", "result: #{result}")
end end
end end
def open_composer def open_composer
params = basic_topic_params params = basic_topic_params
if params[:title].present? && params[:raw].present? if params[:title].present? && params[:raw].present?
url = "/new-topic?title=#{encode_query_param(params[:title])}" url = "/new-topic?title=#{encode_query_param(params[:title])}"
url += "&body=#{encode_query_param(params[:raw])}" url += "&body=#{encode_query_param(params[:raw])}"
if category_id = action_category if category_id = action_category
url += "&category_id=#{category_id}" url += "&category_id=#{category_id}"
end end
if tags = action_tags if tags = action_tags
url += "&tags=#{tags.join(',')}" url += "&tags=#{tags.join(',')}"
end end
route_to = Discourse.base_uri + url route_to = Discourse.base_uri + url
@result.output = data['route_to'] = route_to @result.output = data['route_to'] = route_to
log_success("route: #{route_to}") log_success("route: #{route_to}")
else else
log_error("invalid composer params", "title: #{params[:title]}; post: #{params[:raw]}") log_error("invalid composer params", "title: #{params[:title]}; post: #{params[:raw]}")
end end
end end
def add_to_group def add_to_group
@ -298,14 +299,14 @@ class CustomWizard::Action
multiple: true multiple: true
} }
).perform ).perform
group_map = group_map.flatten.compact group_map = group_map.flatten.compact
unless group_map.present? unless group_map.present?
log_error("invalid group map") log_error("invalid group map")
return return
end end
groups = group_map.reduce([]) do |groups, g| groups = group_map.reduce([]) do |groups, g|
begin begin
groups.push(Integer(g)) groups.push(Integer(g))
@ -313,30 +314,30 @@ class CustomWizard::Action
group = Group.find_by(name: g) group = Group.find_by(name: g)
groups.push(group.id) if group groups.push(group.id) if group
end end
groups groups
end end
result = nil result = nil
if groups.present? if groups.present?
groups.each do |group_id| groups.each do |group_id|
group = Group.find(group_id) if group_id group = Group.find(group_id) if group_id
result = group.add(user) if group result = group.add(user) if group
end end
end end
if result if result
log_success("added to groups", "groups: #{groups.map(&:to_s).join(',')}") log_success("added to groups", "groups: #{groups.map(&:to_s).join(',')}")
else else
detail = groups.present? ? "groups: #{groups.map(&:to_s).join(',')}" : nil detail = groups.present? ? "groups: #{groups.map(&:to_s).join(',')}" : nil
log_error("failed to add to groups", detail) log_error("failed to add to groups", detail)
end end
end end
def route_to def route_to
return unless (url_input = action['url']).present? return unless (url_input = action['url']).present?
if url_input.is_a?(String) if url_input.is_a?(String)
url = mapper.interpolate(url_input) url = mapper.interpolate(url_input)
else else
@ -346,18 +347,18 @@ class CustomWizard::Action
user: user user: user
).perform ).perform
end end
if action['code'] if action['code']
data[action['code']] = SecureRandom.hex(8) data[action['code']] = SecureRandom.hex(8)
url += "&#{action['code']}=#{data[action['code']]}" url += "&#{action['code']}=#{data[action['code']]}"
end end
route_to = UrlHelper.encode(url) route_to = UrlHelper.encode(url)
data['route_to'] = route_to data['route_to'] = route_to
log_info("route: #{route_to}") log_info("route: #{route_to}")
end end
def create_group def create_group
group = group =
begin begin
@ -365,12 +366,12 @@ class CustomWizard::Action
rescue ArgumentError => e rescue ArgumentError => e
raise Discourse::InvalidParameters, "Invalid group params" raise Discourse::InvalidParameters, "Invalid group params"
end end
if group.save if group.save
def get_user_ids(username_string) def get_user_ids(username_string)
User.where(username: username_string.split(",")).pluck(:id) User.where(username: username_string.split(",")).pluck(:id)
end end
if new_group_params[:owner_usernames].present? if new_group_params[:owner_usernames].present?
owner_ids = get_user_ids(new_group_params[:owner_usernames]) owner_ids = get_user_ids(new_group_params[:owner_usernames])
owner_ids.each { |user_id| group.group_users.build(user_id: user_id, owner: true) } owner_ids.each { |user_id| group.group_users.build(user_id: user_id, owner: true) }
@ -381,24 +382,24 @@ class CustomWizard::Action
user_ids -= owner_ids if owner_ids user_ids -= owner_ids if owner_ids
user_ids.each { |user_id| group.group_users.build(user_id: user_id) } user_ids.each { |user_id| group.group_users.build(user_id: user_id) }
end end
GroupActionLogger.new(user, group, skip_guardian: true).log_change_group_settings GroupActionLogger.new(user, group, skip_guardian: true).log_change_group_settings
log_success("Group created", group.name) log_success("Group created", group.name)
result.output = group.name result.output = group.name
else else
log_error("Group creation failed", group.errors.messages) log_error("Group creation failed", group.errors.messages)
end end
end end
def create_category def create_category
category = category =
begin begin
Category.new(new_category_params.merge(user: user)) Category.new(new_category_params.merge(user: user))
rescue ArgumentError => e rescue ArgumentError => e
raise Discourse::InvalidParameters, "Invalid category params" raise Discourse::InvalidParameters, "Invalid category params"
end end
if category.save if category.save
StaffActionLogger.new(user).log_category_creation(category) StaffActionLogger.new(user).log_category_creation(category)
log_success("Category created", category.name) log_success("Category created", category.name)
@ -407,18 +408,18 @@ class CustomWizard::Action
log_error("Category creation failed", category.errors.messages) log_error("Category creation failed", category.errors.messages)
end end
end end
private private
def action_category def action_category
output = CustomWizard::Mapper.new( output = CustomWizard::Mapper.new(
inputs: action['category'], inputs: action['category'],
data: data, data: data,
user: user user: user
).perform ).perform
return false unless output.present? return false unless output.present?
if output.is_a?(Array) if output.is_a?(Array)
output.first output.first
elsif output.is_a?(Integer) elsif output.is_a?(Integer)
@ -427,23 +428,23 @@ class CustomWizard::Action
output.to_i output.to_i
end end
end end
def action_tags def action_tags
output = CustomWizard::Mapper.new( output = CustomWizard::Mapper.new(
inputs: action['tags'], inputs: action['tags'],
data: data, data: data,
user: user, user: user,
).perform ).perform
return false unless output.present? return false unless output.present?
if output.is_a?(Array) if output.is_a?(Array)
output.flatten output.flatten
else output.is_a?(String) else output.is_a?(String)
[*output] [*output]
end end
end end
def add_custom_fields(params = {}) def add_custom_fields(params = {})
if (custom_fields = action['custom_fields']).present? if (custom_fields = action['custom_fields']).present?
field_map = CustomWizard::Mapper.new( field_map = CustomWizard::Mapper.new(
@ -451,26 +452,25 @@ class CustomWizard::Action
data: data, data: data,
user: user user: user
).perform ).perform
registered_fields = CustomWizard::CustomField.cached_list registered_fields = CustomWizard::CustomField.cached_list
field_map.each do |field| field_map.each do |field|
keyArr = field[:key].split('.') keyArr = field[:key].split('.')
value = field[:value] value = field[:value]
if keyArr.length > 1 if keyArr.length > 1
klass = keyArr.first klass = keyArr.first
name = keyArr.last name = keyArr.last
else else
name = keyArr.first name = keyArr.first
end end
registered = registered_fields.select { |f| f[:name] == name } registered = registered_fields.select { |f| f[:name] == name }
if registered.first.present? if registered.first.present?
klass = registered.first[:klass] klass = registered.first[:klass]
end end
if klass === 'topic' if klass === 'topic'
params[:topic_opts] ||= {} params[:topic_opts] ||= {}
params[:topic_opts][:custom_fields] ||= {} params[:topic_opts][:custom_fields] ||= {}
@ -481,15 +481,15 @@ class CustomWizard::Action
end end
end end
end end
params params
end end
def basic_topic_params def basic_topic_params
params = { params = {
skip_validations: true skip_validations: true
} }
params[:title] = CustomWizard::Mapper.new( params[:title] = CustomWizard::Mapper.new(
inputs: action['title'], inputs: action['title'],
data: data, data: data,
@ -499,23 +499,23 @@ class CustomWizard::Action
params[:raw] = action['post_builder'] ? params[:raw] = action['post_builder'] ?
mapper.interpolate(action['post_template']) : mapper.interpolate(action['post_template']) :
data[action['post']] data[action['post']]
params[:import_mode] = ActiveRecord::Type::Boolean.new.cast(action['suppress_notifications']) params[:import_mode] = ActiveRecord::Type::Boolean.new.cast(action['suppress_notifications'])
add_custom_fields(params) add_custom_fields(params)
end end
def public_topic_params def public_topic_params
params = {} params = {}
if category = action_category if category = action_category
params[:category] = category params[:category] = category
end end
if tags = action_tags if tags = action_tags
params[:tags] = tags params[:tags] = tags
end end
if public_topic_fields.any? if public_topic_fields.any?
public_topic_fields.each do |field| public_topic_fields.each do |field|
unless action[field].nil? || action[field] == "" unless action[field].nil? || action[field] == ""
@ -527,13 +527,13 @@ class CustomWizard::Action
end end
end end
end end
params params
end end
def new_group_params def new_group_params
params = {} params = {}
%w( %w(
name name
full_name full_name
@ -548,37 +548,37 @@ class CustomWizard::Action
grant_trust_level grant_trust_level
).each do |attr| ).each do |attr|
input = action[attr] input = action[attr]
if attr === "name" && input.blank? if attr === "name" && input.blank?
raise ArgumentError.new raise ArgumentError.new
end end
if attr === "full_name" && input.blank? if attr === "full_name" && input.blank?
input = action["name"] input = action["name"]
end end
if input.present? if input.present?
value = CustomWizard::Mapper.new( value = CustomWizard::Mapper.new(
inputs: input, inputs: input,
data: data, data: data,
user: user user: user
).perform ).perform
if value if value
value = value.parameterize(separator: '_') if attr === "name" value = value.parameterize(separator: '_') if attr === "name"
value = value.to_i if attr.include?("_level") value = value.to_i if attr.include?("_level")
params[attr.to_sym] = value params[attr.to_sym] = value
end end
end end
end end
add_custom_fields(params) add_custom_fields(params)
end end
def new_category_params def new_category_params
params = {} params = {}
%w( %w(
name name
slug slug
@ -587,61 +587,61 @@ class CustomWizard::Action
parent_category_id parent_category_id
permissions permissions
).each do |attr| ).each do |attr|
if action[attr].present? if action[attr].present?
value = CustomWizard::Mapper.new( value = CustomWizard::Mapper.new(
inputs: action[attr], inputs: action[attr],
data: data, data: data,
user: user user: user
).perform ).perform
if value if value
if attr === "parent_category_id" && value.is_a?(Array) if attr === "parent_category_id" && value.is_a?(Array)
value = value[0] value = value[0]
end end
if attr === "permissions" && value.is_a?(Array) if attr === "permissions" && value.is_a?(Array)
permissions = value permissions = value
value = {} value = {}
permissions.each do |p| permissions.each do |p|
k = p[:key] k = p[:key]
v = p[:value].to_i v = p[:value].to_i
if k.is_a?(Array) if k.is_a?(Array)
group = Group.find_by(id: k[0]) group = Group.find_by(id: k[0])
k = group.name k = group.name
else else
k = k.parameterize(separator: '_') k = k.parameterize(separator: '_')
end end
value[k] = v value[k] = v
end end
end end
if attr === 'slug' if attr === 'slug'
value = value.parameterize(separator: '-') value = value.parameterize(separator: '-')
end end
params[attr.to_sym] = value params[attr.to_sym] = value
end end
end end
end end
add_custom_fields(params) add_custom_fields(params)
end end
def creates_post? def creates_post?
[:create_topic, :send_message].include?(action['type'].to_sym) [:create_topic, :send_message].include?(action['type'].to_sym)
end end
def public_topic_fields def public_topic_fields
['visible'] ['visible']
end end
def profile_url_fields def profile_url_fields
['profile_background', 'card_background'] ['profile_background', 'card_background']
end end
def cast_profile_key(key) def cast_profile_key(key)
if profile_url_fields.include?(key) if profile_url_fields.include?(key)
"#{key}_upload_url" "#{key}_upload_url"
@ -649,10 +649,10 @@ class CustomWizard::Action
key key
end end
end end
def cast_profile_value(value, key) def cast_profile_value(value, key)
return value if value.nil? return value if value.nil?
if profile_url_fields.include?(key) if profile_url_fields.include?(key)
value['url'] value['url']
elsif key === 'avatar' elsif key === 'avatar'
@ -661,26 +661,26 @@ class CustomWizard::Action
value value
end end
end end
def profile_excluded_fields def profile_excluded_fields
['username', 'email', 'trust_level'].freeze ['username', 'email', 'trust_level'].freeze
end end
def allowed_profile_field?(field) def allowed_profile_field?(field)
allowed_profile_fields.include?(field) || user_field?(field) allowed_profile_fields.include?(field) || user_field?(field)
end end
def user_field?(field) def user_field?(field)
field.to_s.include?(::User::USER_FIELD_PREFIX) && field.to_s.include?(::User::USER_FIELD_PREFIX) &&
::UserField.exists?(field.split('_').last.to_i) ::UserField.exists?(field.split('_').last.to_i)
end end
def allowed_profile_fields def allowed_profile_fields
CustomWizard::Mapper.user_fields.select { |f| profile_excluded_fields.exclude?(f) } + CustomWizard::Mapper.user_fields.select { |f| profile_excluded_fields.exclude?(f) } +
profile_url_fields + profile_url_fields +
['avatar'] ['avatar']
end end
def update_avatar(upload_id) def update_avatar(upload_id)
user.create_user_avatar unless user.user_avatar user.create_user_avatar unless user.user_avatar
user.user_avatar.custom_upload_id = upload_id user.user_avatar.custom_upload_id = upload_id
@ -688,34 +688,34 @@ class CustomWizard::Action
user.save! user.save!
user.user_avatar.save! user.user_avatar.save!
end end
def encode_query_param(param) def encode_query_param(param)
Addressable::URI.encode_component(param, Addressable::URI::CharacterClasses::UNRESERVED) Addressable::URI.encode_component(param, Addressable::URI::CharacterClasses::UNRESERVED)
end end
def log_success(message, detail = nil) def log_success(message, detail = nil)
@log.push("success: #{message} - #{detail}") @log.push("success: #{message} - #{detail}")
@result.success = true @result.success = true
end end
def log_error(message, detail = nil) def log_error(message, detail = nil)
@log.push("error: #{message} - #{detail}") @log.push("error: #{message} - #{detail}")
@result.success = false @result.success = false
end end
def log_info(message, detail = nil) def log_info(message, detail = nil)
@log.push("info: #{message} - #{detail}") @log.push("info: #{message} - #{detail}")
end end
def save_log def save_log
log = "wizard: #{@wizard.id}; action: #{action['type']}; user: #{user.username}" log = "wizard: #{@wizard.id}; action: #{action['type']}; user: #{user.username}"
if @log.any? if @log.any?
@log.each do |item| @log.each do |item|
log << "; #{item.to_s}" log += "; #{item.to_s}"
end end
end end
CustomWizard::Log.create(log) CustomWizard::Log.create(log)
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::ActionResult class CustomWizard::ActionResult
attr_accessor :success, :handler, :output attr_accessor :success, :handler, :output

Datei anzeigen

@ -1,10 +1,11 @@
# frozen_string_literal: true
class CustomWizard::Api class CustomWizard::Api
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
attr_accessor :name, attr_accessor :name,
:title :title
def initialize(name, data={}) def initialize(name, data = {})
@name = name @name = name
data.each do |k, v| data.each do |k, v|
self.send "#{k}=", v if self.respond_to?(k) self.send "#{k}=", v if self.respond_to?(k)

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'excon' require 'excon'
class CustomWizard::Api::Authorization class CustomWizard::Api::Authorization
@ -19,7 +20,7 @@ class CustomWizard::Api::Authorization
:username, :username,
:password :password
def initialize(api_name, data={}) def initialize(api_name, data = {})
@api_name = api_name @api_name = api_name
data.each do |k, v| data.each do |k, v|
@ -106,18 +107,18 @@ class CustomWizard::Api::Authorization
connection = Excon.new( connection = Excon.new(
authorization.token_url, authorization.token_url,
:headers => { headers: {
"Content-Type" => "application/x-www-form-urlencoded" "Content-Type" => "application/x-www-form-urlencoded"
}, },
:method => 'GET', method: 'GET',
:query => URI.encode_www_form(body) query: URI.encode_www_form(body)
) )
begin begin
result = connection.request() result = connection.request()
log_params = {time: Time.now, user_id: 0, status: 'SUCCESS', url: authorization.token_url, error: ""} log_params = { time: Time.now, user_id: 0, status: 'SUCCESS', url: authorization.token_url, error: "" }
CustomWizard::Api::LogEntry.set(name, log_params) CustomWizard::Api::LogEntry.set(name, log_params)
rescue SystemCallError => e rescue SystemCallError => e
log_params = {time: Time.now, user_id: 0, status: 'FAILURE', url: authorization.token_url, error: "Token refresh request failed: #{e.inspect}"} log_params = { time: Time.now, user_id: 0, status: 'FAILURE', url: authorization.token_url, error: "Token refresh request failed: #{e.inspect}" }
CustomWizard::Api::LogEntry.set(name, log_params) CustomWizard::Api::LogEntry.set(name, log_params)
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::Api::Endpoint class CustomWizard::Api::Endpoint
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
@ -9,7 +10,7 @@ class CustomWizard::Api::Endpoint
:content_type, :content_type,
:success_codes :success_codes
def initialize(api_name, data={}) def initialize(api_name, data = {})
@api_name = api_name @api_name = api_name
data.each do |k, v| data.each do |k, v|
@ -35,7 +36,7 @@ class CustomWizard::Api::Endpoint
self.get(api_name, endpoint_id) self.get(api_name, endpoint_id)
end end
def self.get(api_name, endpoint_id, opts={}) def self.get(api_name, endpoint_id, opts = {})
return nil if !endpoint_id return nil if !endpoint_id
if data = PluginStore.get("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}") if data = PluginStore.get("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}")
@ -68,7 +69,7 @@ class CustomWizard::Api::Endpoint
endpoint = self.get(api_name, endpoint_id) endpoint = self.get(api_name, endpoint_id)
auth_string = CustomWizard::Api::Authorization.authorization_string(api_name) auth_string = CustomWizard::Api::Authorization.authorization_string(api_name)
content_type = endpoint.content_type content_type = endpoint.content_type
headers = {} headers = {}
headers["Authorization"] = auth_string if auth_string headers["Authorization"] = auth_string if auth_string
headers["Content-Type"] = content_type if content_type headers["Content-Type"] = content_type if content_type
@ -82,13 +83,13 @@ class CustomWizard::Api::Endpoint
body = JSON.generate(body) body = JSON.generate(body)
elsif content_type === "application/x-www-form-urlencoded" elsif content_type === "application/x-www-form-urlencoded"
body = URI.encode_www_form(body) body = URI.encode_www_form(body)
end end
params[:body] = body params[:body] = body
end end
response = connection.request(params) response = connection.request(params)
if endpoint.success_codes.include?(response.status) if endpoint.success_codes.include?(response.status)
begin begin
result = JSON.parse(response.body) result = JSON.parse(response.body)
@ -97,7 +98,7 @@ class CustomWizard::Api::Endpoint
end end
CustomWizard::Api::LogEntry.set(api_name, log_params(user, 'SUCCESS', endpoint.url)) CustomWizard::Api::LogEntry.set(api_name, log_params(user, 'SUCCESS', endpoint.url))
result result
else else
message = "API request failed" message = "API request failed"
@ -105,7 +106,7 @@ class CustomWizard::Api::Endpoint
{ error: message } { error: message }
end end
end end
def self.log_params(user, status, url, message = "") def self.log_params(user, status, url, message = "")
{ time: Time.now, user_id: user.id, status: status, url: url, error: message } { time: Time.now, user_id: user.id, status: status, url: url, error: message }
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::Api::LogEntry class CustomWizard::Api::LogEntry
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
@ -12,7 +13,7 @@ class CustomWizard::Api::LogEntry
:name, :name,
:avatar_template :avatar_template
def initialize(api_name, data={}) def initialize(api_name, data = {})
@api_name = api_name @api_name = api_name
data.each do |k, v| data.each do |k, v|
@ -38,7 +39,7 @@ class CustomWizard::Api::LogEntry
self.get(api_name, log_id) self.get(api_name, log_id)
end end
def self.get(api_name, log_id, opts={}) def self.get(api_name, log_id, opts = {})
return nil if !log_id return nil if !log_id
if data = PluginStore.get("custom_wizard_api_#{api_name}", "log_#{log_id}") if data = PluginStore.get("custom_wizard_api_#{api_name}", "log_#{log_id}")

Datei anzeigen

@ -1,10 +1,11 @@
# frozen_string_literal: true
class CustomWizard::Builder class CustomWizard::Builder
attr_accessor :wizard, :updater, :submissions attr_accessor :wizard, :updater, :submissions
def initialize(wizard_id, user=nil) def initialize(wizard_id, user = nil)
template = CustomWizard::Template.find(wizard_id) template = CustomWizard::Template.find(wizard_id)
return nil if template.blank? return nil if template.blank?
@wizard = CustomWizard::Wizard.new(template, user) @wizard = CustomWizard::Wizard.new(template, user)
@steps = template['steps'] || [] @steps = template['steps'] || []
@actions = template['actions'] || [] @actions = template['actions'] || []
@ -23,7 +24,7 @@ class CustomWizard::Builder
sorted_handlers << { priority: priority, wizard_id: wizard_id, block: block } sorted_handlers << { priority: priority, wizard_id: wizard_id, block: block }
@sorted_handlers.sort_by! { |h| -h[:priority] } @sorted_handlers.sort_by! { |h| -h[:priority] }
end end
def mapper def mapper
CustomWizard::Mapper.new( CustomWizard::Mapper.new(
user: @wizard.user, user: @wizard.user,
@ -34,36 +35,36 @@ class CustomWizard::Builder
def build(build_opts = {}, params = {}) def build(build_opts = {}, params = {})
return nil if !SiteSetting.custom_wizard_enabled || !@wizard return nil if !SiteSetting.custom_wizard_enabled || !@wizard
return @wizard if !@wizard.can_access? return @wizard if !@wizard.can_access?
build_opts[:reset] = build_opts[:reset] || @wizard.restart_on_revisit build_opts[:reset] = build_opts[:reset] || @wizard.restart_on_revisit
@steps.each do |step_template| @steps.each do |step_template|
@wizard.append_step(step_template['id']) do |step| @wizard.append_step(step_template['id']) do |step|
step.permitted = true step.permitted = true
if step_template['required_data'] if step_template['required_data']
step = ensure_required_data(step, step_template) step = ensure_required_data(step, step_template)
end end
if !step.permitted if !step.permitted
if step_template['required_data_message'] if step_template['required_data_message']
step.permitted_message = step_template['required_data_message'] step.permitted_message = step_template['required_data_message']
end end
next next
end end
step.title = step_template['title'] if step_template['title'] step.title = step_template['title'] if step_template['title']
step.banner = step_template['banner'] if step_template['banner'] step.banner = step_template['banner'] if step_template['banner']
step.key = step_template['key'] if step_template['key'] step.key = step_template['key'] if step_template['key']
if step_template['description'] if step_template['description']
step.description = mapper.interpolate( step.description = mapper.interpolate(
step_template['description'], step_template['description'],
user: true, user: true,
value: true value: true
) )
end end
if permitted_params = step_template['permitted_params'] if permitted_params = step_template['permitted_params']
save_permitted_params(permitted_params, params) save_permitted_params(permitted_params, params)
end end
@ -77,9 +78,9 @@ class CustomWizard::Builder
step.on_update do |updater| step.on_update do |updater|
@updater = updater @updater = updater
user = @wizard.user user = @wizard.user
updater.validate updater.validate
next if updater.errors.any? next if updater.errors.any?
CustomWizard::Builder.step_handlers.each do |handler| CustomWizard::Builder.step_handlers.each do |handler|
@ -95,15 +96,15 @@ class CustomWizard::Builder
if current_submission = @wizard.current_submission if current_submission = @wizard.current_submission
submission = current_submission.merge(submission) submission = current_submission.merge(submission)
end end
final_step = updater.step.next.nil? final_step = updater.step.next.nil?
if @actions.present? if @actions.present?
@actions.each do |action| @actions.each do |action|
if (action['run_after'] === updater.step.id) || if (action['run_after'] === updater.step.id) ||
(final_step && (!action['run_after'] || (action['run_after'] === 'wizard_completion'))) (final_step && (!action['run_after'] || (action['run_after'] === 'wizard_completion')))
CustomWizard::Action.new( CustomWizard::Action.new(
wizard: @wizard, wizard: @wizard,
action: action, action: action,
@ -113,28 +114,28 @@ class CustomWizard::Builder
end end
end end
end end
if updater.errors.empty? if updater.errors.empty?
if route_to = submission['route_to'] if route_to = submission['route_to']
submission.delete('route_to') submission.delete('route_to')
end end
if @wizard.save_submissions if @wizard.save_submissions
save_submissions(submission, final_step) save_submissions(submission, final_step)
end end
if final_step if final_step
if @wizard.id == @wizard.user.custom_fields['redirect_to_wizard'] if @wizard.id == @wizard.user.custom_fields['redirect_to_wizard']
@wizard.user.custom_fields.delete('redirect_to_wizard'); @wizard.user.custom_fields.delete('redirect_to_wizard')
@wizard.user.save_custom_fields(true) @wizard.user.save_custom_fields(true)
end end
redirect_url = route_to || submission['redirect_on_complete'] || submission["redirect_to"] redirect_url = route_to || submission['redirect_on_complete'] || submission["redirect_to"]
updater.result[:redirect_on_complete] = redirect_url updater.result[:redirect_on_complete] = redirect_url
elsif route_to elsif route_to
updater.result[:redirect_on_next] = route_to updater.result[:redirect_on_next] = route_to
end end
true true
else else
false false
@ -142,7 +143,7 @@ class CustomWizard::Builder
end end
end end
end end
@wizard @wizard
end end
@ -153,7 +154,7 @@ class CustomWizard::Builder
required: field_template['required'], required: field_template['required'],
number: index + 1 number: index + 1
} }
params[:label] = field_template['label'] if field_template['label'] params[:label] = field_template['label'] if field_template['label']
params[:description] = field_template['description'] if field_template['description'] params[:description] = field_template['description'] if field_template['description']
params[:image] = field_template['image'] if field_template['image'] params[:image] = field_template['image'] if field_template['image']
@ -163,11 +164,11 @@ class CustomWizard::Builder
params[:max_length] = field_template['max_length'] if field_template['max_length'] params[:max_length] = field_template['max_length'] if field_template['max_length']
params[:char_counter] = field_template['char_counter'] if field_template['char_counter'] params[:char_counter] = field_template['char_counter'] if field_template['char_counter']
params[:value] = prefill_field(field_template, step_template) params[:value] = prefill_field(field_template, step_template)
if !build_opts[:reset] && (submission = @wizard.current_submission) if !build_opts[:reset] && (submission = @wizard.current_submission)
params[:value] = submission[field_template['id']] if submission[field_template['id']] params[:value] = submission[field_template['id']] if submission[field_template['id']]
end end
if field_template['type'] === 'group' && params[:value].present? if field_template['type'] === 'group' && params[:value].present?
params[:value] = params[:value].first params[:value] = params[:value].first
end end
@ -179,19 +180,19 @@ class CustomWizard::Builder
if field_template['type'] === 'upload' if field_template['type'] === 'upload'
params[:file_types] = field_template['file_types'] params[:file_types] = field_template['file_types']
end end
if ['date', 'time', 'date_time'].include?(field_template['type']) if ['date', 'time', 'date_time'].include?(field_template['type'])
params[:format] = field_template['format'] params[:format] = field_template['format']
end end
if field_template['type'] === 'category' || field_template['type'] === 'tag' if field_template['type'] === 'category' || field_template['type'] === 'tag'
params[:limit] = field_template['limit'] params[:limit] = field_template['limit']
end end
if field_template['type'] === 'category' if field_template['type'] === 'category'
params[:property] = field_template['property'] params[:property] = field_template['property']
end end
if field_template['type'] === 'category' || ( if field_template['type'] === 'category' || (
field_template['validations'] && field_template['validations'] &&
field_template['validations']['similar_topics'] && field_template['validations']['similar_topics'] &&
@ -199,11 +200,11 @@ class CustomWizard::Builder
) )
@wizard.needs_categories = true @wizard.needs_categories = true
end end
if field_template['type'] === 'group' if field_template['type'] === 'group'
@wizard.needs_groups = true @wizard.needs_groups = true
end end
if (content_inputs = field_template['content']).present? if (content_inputs = field_template['content']).present?
content = CustomWizard::Mapper.new( content = CustomWizard::Mapper.new(
inputs: content_inputs, inputs: content_inputs,
@ -213,35 +214,35 @@ class CustomWizard::Builder
with_type: true with_type: true
} }
).perform ).perform
if content.present? && if content.present? &&
content[:result].present? content[:result].present?
if content[:type] == 'association' if content[:type] == 'association'
content[:result] = content[:result].map do |item| content[:result] = content[:result].map do |item|
{ {
id: item[:key], id: item[:key],
name: item[:value] name: item[:value]
} }
end end
end end
if content[:type] == 'assignment' && field_template['type'] === 'dropdown' if content[:type] == 'assignment' && field_template['type'] === 'dropdown'
content[:result] = content[:result].map do |item| content[:result] = content[:result].map do |item|
{ {
id: item, id: item,
name: item name: item
} }
end end
end end
params[:content] = content[:result] params[:content] = content[:result]
end end
end end
field = step.add_field(params) field = step.add_field(params)
end end
def prefill_field(field_template, step_template) def prefill_field(field_template, step_template)
if (prefill = field_template['prefill']).present? if (prefill = field_template['prefill']).present?
CustomWizard::Mapper.new( CustomWizard::Mapper.new(
@ -267,7 +268,7 @@ class CustomWizard::Builder
@wizard.set_submissions(@submissions) @wizard.set_submissions(@submissions)
end end
end end
def save_permitted_params(permitted_params, params) def save_permitted_params(permitted_params, params)
permitted_data = {} permitted_data = {}
@ -283,28 +284,28 @@ class CustomWizard::Builder
save_submissions(current_data.merge(permitted_data), false) save_submissions(current_data.merge(permitted_data), false)
end end
end end
def ensure_required_data(step, step_template) def ensure_required_data(step, step_template)
step_template['required_data'].each do |required| step_template['required_data'].each do |required|
pairs = required['pairs'].select do |pair| pairs = required['pairs'].select do |pair|
pair['key'].present? && pair['value'].present? pair['key'].present? && pair['value'].present?
end end
if pairs.any? && !@submissions.last if pairs.any? && !@submissions.last
step.permitted = false step.permitted = false
break break
end end
pairs.each do |pair| pairs.each do |pair|
pair['key'] = @submissions.last[pair['key']] pair['key'] = @submissions.last[pair['key']]
end end
if !mapper.validate_pairs(pairs) if !mapper.validate_pairs(pairs)
step.permitted = false step.permitted = false
break break
end end
end end
step step
end end
end end

Datei anzeigen

@ -4,30 +4,30 @@ class ::CustomWizard::Cache
def initialize(key) def initialize(key)
@key = "#{CustomWizard::PLUGIN_NAME}_#{key}" @key = "#{CustomWizard::PLUGIN_NAME}_#{key}"
end end
def read def read
cache.read(@key) cache.read(@key)
end end
def write(data) def write(data)
synchronize { cache.write(@key, data) } synchronize { cache.write(@key, data) }
end end
def delete def delete
synchronize { cache.delete(@key) } synchronize { cache.delete(@key) }
end end
def synchronize def synchronize
DistributedMutex.synchronize(@key) { yield } DistributedMutex.synchronize(@key) { yield }
end end
def cache def cache
@cache ||= Discourse.cache @cache ||= Discourse.cache
end end
def self.wrap(key, &block) def self.wrap(key, &block)
c = new(key) c = new(key)
if cached = c.read if cached = c.read
cached cached
else else
@ -36,4 +36,4 @@ class ::CustomWizard::Cache
result result
end end
end end
end end

Datei anzeigen

@ -3,14 +3,14 @@
class ::CustomWizard::CustomField class ::CustomWizard::CustomField
include HasErrors include HasErrors
include ActiveModel::Serialization include ActiveModel::Serialization
attr_reader :id attr_reader :id
ATTRS ||= ["name", "klass", "type", "serializers"] ATTRS ||= ["name", "klass", "type", "serializers"]
REQUIRED ||= ["name", "klass", "type"] REQUIRED ||= ["name", "klass", "type"]
NAMESPACE ||= "custom_wizard_custom_fields" NAMESPACE ||= "custom_wizard_custom_fields"
NAME_MIN_LENGTH ||= 3 NAME_MIN_LENGTH ||= 3
CLASSES ||= { CLASSES ||= {
topic: ["topic_view", "topic_list_item"], topic: ["topic_view", "topic_list_item"],
group: ["basic_group"], group: ["basic_group"],
@ -19,20 +19,20 @@ class ::CustomWizard::CustomField
} }
TYPES ||= ["string", "boolean", "integer", "json"] TYPES ||= ["string", "boolean", "integer", "json"]
LIST_CACHE_KEY ||= 'custom_field_list' LIST_CACHE_KEY ||= 'custom_field_list'
def self.serializers def self.serializers
CLASSES.values.flatten.uniq CLASSES.values.flatten.uniq
end end
def initialize(id, data) def initialize(id, data)
@id = id @id = id
data = data.with_indifferent_access data = data.with_indifferent_access
ATTRS.each do |attr| ATTRS.each do |attr|
self.class.class_eval { attr_accessor attr } self.class.class_eval { attr_accessor attr }
value = data[attr] value = data[attr]
if value.present? if value.present?
send("#{attr}=", value) send("#{attr}=", value)
end end
@ -45,11 +45,11 @@ class ::CustomWizard::CustomField
if valid? if valid?
data = {} data = {}
key = name key = name
(ATTRS - ['name']).each do |attr| (ATTRS - ['name']).each do |attr|
data[attr] = send(attr) data[attr] = send(attr)
end end
if self.class.save_to_store(id, key, data) if self.class.save_to_store(id, key, data)
self.class.invalidate_cache self.class.invalidate_cache
true true
@ -60,50 +60,49 @@ class ::CustomWizard::CustomField
false false
end end
end end
def validate def validate
ATTRS.each do |attr| ATTRS.each do |attr|
value = send(attr) value = send(attr)
i18n_key = "wizard.custom_field.error" i18n_key = "wizard.custom_field.error"
if value.blank? if value.blank?
if REQUIRED.include?(attr) if REQUIRED.include?(attr)
add_error(I18n.t("#{i18n_key}.required_attribute", attr: attr)) add_error(I18n.t("#{i18n_key}.required_attribute", attr: attr))
end end
next next
end end
if (attr == 'klass' && CLASSES.keys.exclude?(value.to_sym)) || if (attr == 'klass' && CLASSES.keys.exclude?(value.to_sym)) ||
(attr == 'serializers' && CLASSES[klass.to_sym].blank?) (attr == 'serializers' && CLASSES[klass.to_sym].blank?)
add_error(I18n.t("#{i18n_key}.unsupported_class", class: value)) add_error(I18n.t("#{i18n_key}.unsupported_class", class: value))
next next
end end
if attr == 'serializers' && (unsupported = value - CLASSES[klass.to_sym]).length > 0 if attr == 'serializers' && (unsupported = value - CLASSES[klass.to_sym]).length > 0
add_error(I18n.t("#{i18n_key}.unsupported_serializers", add_error(I18n.t("#{i18n_key}.unsupported_serializers",
class: klass, class: klass,
serializers: unsupported.join(", ") serializers: unsupported.join(", ")
)) ))
end end
if attr == 'type' && TYPES.exclude?(value) if attr == 'type' && TYPES.exclude?(value)
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value)) add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
end end
if attr == 'name' if attr == 'name'
unless value.is_a?(String) unless value.is_a?(String)
add_error(I18n.t("#{i18n_key}.name_invalid", name: value)) add_error(I18n.t("#{i18n_key}.name_invalid", name: value))
end end
if value.length < NAME_MIN_LENGTH if value.length < NAME_MIN_LENGTH
add_error(I18n.t("#{i18n_key}.name_too_short", name: value, min_length: NAME_MIN_LENGTH)) add_error(I18n.t("#{i18n_key}.name_too_short", name: value, min_length: NAME_MIN_LENGTH))
end end
if new? && self.class.exists?(name) if new? && self.class.exists?(name)
add_error(I18n.t("#{i18n_key}.name_already_taken", name: value)) add_error(I18n.t("#{i18n_key}.name_already_taken", name: value))
end end
begin begin
@name = value.parameterize(separator: '_') @name = value.parameterize(separator: '_')
rescue rescue
@ -112,21 +111,21 @@ class ::CustomWizard::CustomField
end end
end end
end end
def new? def new?
id.blank? id.blank?
end end
def valid? def valid?
errors.blank? errors.blank?
end end
def self.list def self.list
PluginStoreRow.where(plugin_name: NAMESPACE).map do |record| PluginStoreRow.where(plugin_name: NAMESPACE).map do |record|
create_from_store(record) create_from_store(record)
end end
end end
def self.cached_list def self.cached_list
::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do ::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do
PluginStoreRow.where(plugin_name: NAMESPACE).map do |record| PluginStoreRow.where(plugin_name: NAMESPACE).map do |record|
@ -134,11 +133,11 @@ class ::CustomWizard::CustomField
end end
end end
end end
def self.list_by(attr, value, cached: true) def self.list_by(attr, value, cached: true)
attr = attr.to_sym attr = attr.to_sym
fields = cached ? cached_list : list fields = cached ? cached_list : list
fields.select do |cf| fields.select do |cf|
if attr == :serializers if attr == :serializers
cf[attr].include?(value) cf[attr].include?(value)
@ -147,38 +146,38 @@ class ::CustomWizard::CustomField
end end
end end
end end
def self.exists?(name) def self.exists?(name)
PluginStoreRow.where(plugin_name: NAMESPACE, key: name).exists? PluginStoreRow.where(plugin_name: NAMESPACE, key: name).exists?
end end
def self.find(field_id) def self.find(field_id)
record = PluginStoreRow.find_by(id: field_id, plugin_name: NAMESPACE) record = PluginStoreRow.find_by(id: field_id, plugin_name: NAMESPACE)
if record if record
create_from_store(record) create_from_store(record)
else else
false false
end end
end end
def self.find_by_name(name) def self.find_by_name(name)
record = PluginStoreRow.find_by(key: name, plugin_name: NAMESPACE) record = PluginStoreRow.find_by(key: name, plugin_name: NAMESPACE)
if record if record
create_from_store(record) create_from_store(record)
else else
false false
end end
end end
def self.create_from_store(record) def self.create_from_store(record)
data = JSON.parse(record.value) data = JSON.parse(record.value)
data[:name] = record.key data[:name] = record.key
new(record.id, data) new(record.id, data)
end end
def self.save_to_store(id = nil, key, data) def self.save_to_store(id = nil, key, data)
if id if id
record = PluginStoreRow.find_by(id: id, plugin_name: NAMESPACE) record = PluginStoreRow.find_by(id: id, plugin_name: NAMESPACE)
return false if !record return false if !record
@ -192,7 +191,7 @@ class ::CustomWizard::CustomField
record.save record.save
end end
end end
def self.destroy(name) def self.destroy(name)
if exists?(name) if exists?(name)
PluginStoreRow.where(plugin_name: NAMESPACE, key: name).destroy_all PluginStoreRow.where(plugin_name: NAMESPACE, key: name).destroy_all
@ -202,18 +201,18 @@ class ::CustomWizard::CustomField
false false
end end
end end
def self.invalidate_cache def self.invalidate_cache
CustomWizard::Cache.new(LIST_CACHE_KEY).delete CustomWizard::Cache.new(LIST_CACHE_KEY).delete
Discourse.clear_readonly! Discourse.clear_readonly!
Discourse.request_refresh! Discourse.request_refresh!
end end
def self.any? def self.any?
cached_list.length > 0 cached_list.length > 0
end end
def self.enabled? def self.enabled?
any? any?
end end
end end

Datei anzeigen

@ -2,9 +2,9 @@
module ::CustomWizard module ::CustomWizard
PLUGIN_NAME ||= 'custom_wizard' PLUGIN_NAME ||= 'custom_wizard'
class Engine < ::Rails::Engine class Engine < ::Rails::Engine
engine_name PLUGIN_NAME engine_name PLUGIN_NAME
isolate_namespace CustomWizard isolate_namespace CustomWizard
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::Field class CustomWizard::Field
def self.types def self.types
@types ||= { @types ||= {
@ -64,7 +65,7 @@ class CustomWizard::Field
@require_assets ||= {} @require_assets ||= {}
end end
def self.register(type, plugin = nil, asset_paths = [], opts={}) def self.register(type, plugin = nil, asset_paths = [], opts = {})
if type if type
types[type.to_sym] ||= {} types[type.to_sym] ||= {}
types[type.to_sym] = opts[:type_opts] if opts[:type_opts].present? types[type.to_sym] = opts[:type_opts] if opts[:type_opts].present?

Datei anzeigen

@ -1,18 +1,19 @@
# frozen_string_literal: true
class CustomWizard::Log class CustomWizard::Log
include ActiveModel::Serialization include ActiveModel::Serialization
attr_accessor :message, :date attr_accessor :message, :date
PAGE_LIMIT = 100 PAGE_LIMIT = 100
def initialize(attrs) def initialize(attrs)
@message = attrs['message'] @message = attrs['message']
@date = attrs['date'] @date = attrs['date']
end end
def self.create(message) def self.create(message)
log_id = SecureRandom.hex(12) log_id = SecureRandom.hex(12)
PluginStore.set('custom_wizard_log', PluginStore.set('custom_wizard_log',
log_id.to_s, log_id.to_s,
{ {
@ -21,20 +22,20 @@ class CustomWizard::Log
} }
) )
end end
def self.list_query def self.list_query
PluginStoreRow.where(" PluginStoreRow.where("
plugin_name = 'custom_wizard_log' AND plugin_name = 'custom_wizard_log' AND
(value::json->'date') IS NOT NULL (value::json->'date') IS NOT NULL
").order("value::json->>'date' DESC") ").order("value::json->>'date' DESC")
end end
def self.list(page = 0, limit = nil) def self.list(page = 0, limit = nil)
limit = limit.to_i > 0 ? limit.to_i : PAGE_LIMIT limit = limit.to_i > 0 ? limit.to_i : PAGE_LIMIT
page = page.to_i page = page.to_i
self.list_query.limit(limit) self.list_query.limit(limit)
.offset(page * limit) .offset(page * limit)
.map { |r| self.new(JSON.parse(r.value)) } .map { |r| self.new(JSON.parse(r.value)) }
end end
end end

Datei anzeigen

@ -1,25 +1,26 @@
# frozen_string_literal: true
class CustomWizard::Mapper class CustomWizard::Mapper
attr_accessor :inputs, :data, :user attr_accessor :inputs, :data, :user
USER_FIELDS = [ USER_FIELDS = [
'name', 'name',
'username', 'username',
'email', 'email',
'date_of_birth', 'date_of_birth',
'title', 'title',
'locale', 'locale',
'trust_level', 'trust_level',
'email_level', 'email_level',
'email_messages_level', 'email_messages_level',
'email_digests' 'email_digests'
] ]
PROFILE_FIELDS = ['location', 'website', 'bio_raw'] PROFILE_FIELDS = ['location', 'website', 'bio_raw']
def self.user_fields def self.user_fields
USER_FIELDS + PROFILE_FIELDS USER_FIELDS + PROFILE_FIELDS
end end
OPERATORS = { OPERATORS = {
equal: '==', equal: '==',
greater: '>', greater: '>',
@ -33,28 +34,28 @@ class CustomWizard::Mapper
false: "==" false: "=="
} }
} }
def initialize(params) def initialize(params)
@inputs = params[:inputs] || {} @inputs = params[:inputs] || {}
@data = params[:data] || {} @data = params[:data] || {}
@user = params[:user] @user = params[:user]
@opts = params[:opts] || {} @opts = params[:opts] || {}
end end
def perform def perform
multiple = @opts[:multiple] multiple = @opts[:multiple]
perform_result = multiple ? [] : nil perform_result = multiple ? [] : nil
inputs.each do |input| inputs.each do |input|
input_type = input['type'] input_type = input['type']
pairs = input['pairs'] pairs = input['pairs']
if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment' if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment'
output = input['output'] output = input['output']
output_type = input['output_type'] output_type = input['output_type']
result = build_result(map_field(output, output_type), input_type) result = build_result(map_field(output, output_type), input_type)
if multiple if multiple
perform_result.push(result) perform_result.push(result)
else else
@ -62,10 +63,10 @@ class CustomWizard::Mapper
break break
end end
end end
if input_type === 'validation' if input_type === 'validation'
result = build_result(validate_pairs(pairs), input_type) result = build_result(validate_pairs(pairs), input_type)
if multiple if multiple
perform_result.push(result) perform_result.push(result)
else else
@ -73,10 +74,10 @@ class CustomWizard::Mapper
break break
end end
end end
if input_type === 'association' if input_type === 'association'
result = build_result(map_pairs(pairs), input_type) result = build_result(map_pairs(pairs), input_type)
if multiple if multiple
perform_result.push(result) perform_result.push(result)
else else
@ -85,10 +86,10 @@ class CustomWizard::Mapper
end end
end end
end end
perform_result perform_result
end end
def build_result(result, type) def build_result(result, type)
if @opts[:with_type] if @opts[:with_type]
{ {
@ -99,7 +100,7 @@ class CustomWizard::Mapper
result result
end end
end end
def validate_pairs(pairs) def validate_pairs(pairs)
pairs.all? do |pair| pairs.all? do |pair|
connector = pair['connector'] connector = pair['connector']
@ -113,7 +114,7 @@ class CustomWizard::Mapper
end end
end end
end end
def cast_value(value, key, connector) def cast_value(value, key, connector)
if connector == 'regex' if connector == 'regex'
Regexp.new(value) Regexp.new(value)
@ -127,10 +128,10 @@ class CustomWizard::Mapper
end end
end end
end end
def validation_result(key, value, operator) def validation_result(key, value, operator)
result = nil result = nil
if operator.is_a?(Hash) && (operator = operator[value.to_sym]).present? if operator.is_a?(Hash) && (operator = operator[value.to_sym]).present?
if value == "present" if value == "present"
result = key.public_send(operator) result = key.public_send(operator)
@ -142,21 +143,21 @@ class CustomWizard::Mapper
else else
result = false result = false
end end
if operator == '=~' if operator == '=~'
result.nil? ? false : true result.nil? ? false : true
else else
result result
end end
end end
def map_pairs(pairs) def map_pairs(pairs)
result = [] result = []
pairs.each do |pair| pairs.each do |pair|
key = map_field(pair['key'], pair['key_type']) key = map_field(pair['key'], pair['key_type'])
value = map_field(pair['value'], pair['value_type']) value = map_field(pair['value'], pair['value_type'])
if key && value if key && value
result.push( result.push(
key: key, key: key,
@ -164,32 +165,32 @@ class CustomWizard::Mapper
) )
end end
end end
result result
end end
def map_operator(connector) def map_operator(connector)
OPERATORS[connector.to_sym] || '==' OPERATORS[connector.to_sym] || '=='
end end
def map_field(value, type) def map_field(value, type)
method = "map_#{type}" method = "map_#{type}"
if self.respond_to?(method) if self.respond_to?(method)
self.send(method, value) self.send(method, value)
else else
value value
end end
end end
def map_text(value) def map_text(value)
interpolate(value) interpolate(value)
end end
def map_wizard_field(value) def map_wizard_field(value)
data && !data.key?("submitted_at") && data[value] data && !data.key?("submitted_at") && data[value]
end end
def map_wizard_action(value) def map_wizard_action(value)
data && !data.key?("submitted_at") && data[value] data && !data.key?("submitted_at") && data[value]
end end
@ -203,7 +204,7 @@ class CustomWizard::Mapper
User.find(user.id).send(value) User.find(user.id).send(value)
end end
end end
def map_user_field_options(value) def map_user_field_options(value)
if value.include?(User::USER_FIELD_PREFIX) if value.include?(User::USER_FIELD_PREFIX)
if field = UserField.find_by(id: value.split('_').last) if field = UserField.find_by(id: value.split('_').last)
@ -211,10 +212,10 @@ class CustomWizard::Mapper
end end
end end
end end
def interpolate(string, opts={ user: true, wizard: true, value: true }) def interpolate(string, opts = { user: true, wizard: true, value: true })
return string if string.blank? return string if string.blank?
if opts[:user] if opts[:user]
string.gsub!(/u\{(.*?)\}/) do |match| string.gsub!(/u\{(.*?)\}/) do |match|
result = '' result = ''
@ -223,21 +224,21 @@ class CustomWizard::Mapper
result result
end end
end end
if opts[:wizard] if opts[:wizard]
string.gsub!(/w\{(.*?)\}/) do |match| string.gsub!(/w\{(.*?)\}/) do |match|
value = recurse(data, [*$1.split('.')]) value = recurse(data, [*$1.split('.')])
value.present? ? value : '' value.present? ? value : ''
end end
end end
if opts[:value] if opts[:value]
string.gsub!(/v\{(.*?)\}/) do |match| string.gsub!(/v\{(.*?)\}/) do |match|
attrs = $1.split(':') attrs = $1.split(':')
key = attrs.first key = attrs.first
format = attrs.last if attrs.length > 1 format = attrs.last if attrs.length > 1
result = '' result = ''
if key == 'time' if key == 'time'
time_format = format.present? ? format : "%B %-d, %Y" time_format = format.present? ? format : "%B %-d, %Y"
result = Time.now.strftime(time_format) result = Time.now.strftime(time_format)
@ -246,10 +247,10 @@ class CustomWizard::Mapper
result result
end end
end end
string string
end end
def recurse(data, keys) def recurse(data, keys)
return nil if data.nil? return nil if data.nil?
k = keys.shift k = keys.shift

Datei anzeigen

@ -2,7 +2,7 @@
class CustomWizard::RealtimeValidation class CustomWizard::RealtimeValidation
cattr_accessor :types cattr_accessor :types
@@types ||= { @@types ||= {
similar_topics: { similar_topics: {
types: [:text], types: [:text],

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::RealtimeValidation::Result class CustomWizard::RealtimeValidation::Result
attr_accessor :type, attr_accessor :type,
:items, :items,
@ -8,4 +9,4 @@ class CustomWizard::RealtimeValidation::Result
@items = [] @items = []
@serializer_opts = {} @serializer_opts = {}
end end
end end

Datei anzeigen

@ -1,10 +1,11 @@
# frozen_string_literal: true
class CustomWizard::RealtimeValidation::SimilarTopics class CustomWizard::RealtimeValidation::SimilarTopics
attr_accessor :user attr_accessor :user
def initialize(user) def initialize(user)
@user = user @user = user
end end
class SimilarTopic class SimilarTopic
def initialize(topic) def initialize(topic)
@topic = topic @topic = topic
@ -16,7 +17,7 @@ class CustomWizard::RealtimeValidation::SimilarTopics
Search::GroupedSearchResults.blurb_for(cooked: @topic.try(:blurb)) Search::GroupedSearchResults.blurb_for(cooked: @topic.try(:blurb))
end end
end end
def perform(params) def perform(params)
title = params[:title] title = params[:title]
raw = params[:raw] raw = params[:raw]
@ -25,7 +26,7 @@ class CustomWizard::RealtimeValidation::SimilarTopics
time_unit = params[:time_unit] time_unit = params[:time_unit]
result = CustomWizard::RealtimeValidation::Result.new(:similar_topic) result = CustomWizard::RealtimeValidation::Result.new(:similar_topic)
if title.length < SiteSetting.min_title_similar_length || !Topic.count_exceeds_minimum? if title.length < SiteSetting.min_title_similar_length || !Topic.count_exceeds_minimum?
return result return result
end end
@ -38,10 +39,10 @@ class CustomWizard::RealtimeValidation::SimilarTopics
end end
topics.map! { |t| SimilarTopic.new(t) } topics.map! { |t| SimilarTopic.new(t) }
result.items = topics result.items = topics
result.serializer_opts = { root: :similar_topics } result.serializer_opts = { root: :similar_topics }
result result
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::StepUpdater class CustomWizard::StepUpdater
include ActiveModel::Model include ActiveModel::Model
@ -17,9 +18,9 @@ class CustomWizard::StepUpdater
@step.present? && @step.present? &&
@step.updater.present? && @step.updater.present? &&
success? success?
@step.updater.call(self) @step.updater.call(self)
UserHistory.create( UserHistory.create(
action: UserHistory.actions[:custom_wizard_step], action: UserHistory.actions[:custom_wizard_step],
acting_user_id: @current_user.id, acting_user_id: @current_user.id,
@ -38,7 +39,7 @@ class CustomWizard::StepUpdater
def refresh_required? def refresh_required?
@refresh_required @refresh_required
end end
def validate def validate
CustomWizard::UpdateValidator.new(self).perform CustomWizard::UpdateValidator.new(self).perform
end end

Datei anzeigen

@ -2,87 +2,87 @@
class CustomWizard::Template class CustomWizard::Template
include HasErrors include HasErrors
attr_reader :data, attr_reader :data,
:opts :opts
def initialize(data) def initialize(data)
@data = data @data = data
end end
def save(opts={}) def save(opts = {})
@opts = opts @opts = opts
normalize_data normalize_data
validate_data validate_data
prepare_data prepare_data
return false if errors.any? return false if errors.any?
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
schedule_save_jobs unless opts[:skip_jobs] schedule_save_jobs unless opts[:skip_jobs]
PluginStore.set(CustomWizard::PLUGIN_NAME, @data[:id], @data) PluginStore.set(CustomWizard::PLUGIN_NAME, @data[:id], @data)
end end
@data[:id] @data[:id]
end end
def self.save(data, opts={}) def self.save(data, opts = {})
new(data).save(opts) new(data).save(opts)
end end
def self.find(wizard_id) def self.find(wizard_id)
PluginStore.get(CustomWizard::PLUGIN_NAME, wizard_id) PluginStore.get(CustomWizard::PLUGIN_NAME, wizard_id)
end end
def self.remove(wizard_id) def self.remove(wizard_id)
wizard = CustomWizard::Wizard.create(wizard_id) wizard = CustomWizard::Wizard.create(wizard_id)
return false if !wizard return false if !wizard
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id) PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id)
if wizard.after_time if wizard.after_time
Jobs.cancel_scheduled_job(:set_after_time_wizard) Jobs.cancel_scheduled_job(:set_after_time_wizard)
Jobs.enqueue(:clear_after_time_wizard, wizard_id: wizard_id) Jobs.enqueue(:clear_after_time_wizard, wizard_id: wizard_id)
end end
end end
true true
end end
def self.exists?(wizard_id) def self.exists?(wizard_id)
PluginStoreRow.exists?(plugin_name: 'custom_wizard', key: wizard_id) PluginStoreRow.exists?(plugin_name: 'custom_wizard', key: wizard_id)
end end
def self.list(setting: nil, order: :id) def self.list(setting: nil, order: :id)
query = "plugin_name = 'custom_wizard'" query = "plugin_name = 'custom_wizard'"
query += "AND (value::json ->> '#{setting}')::boolean IS TRUE" if setting query += "AND (value::json ->> '#{setting}')::boolean IS TRUE" if setting
PluginStoreRow.where(query).order(order) PluginStoreRow.where(query).order(order)
.reduce([]) do |result, record| .reduce([]) do |result, record|
attrs = JSON.parse(record.value) attrs = JSON.parse(record.value)
if attrs.present? && if attrs.present? &&
attrs.is_a?(Hash) && attrs.is_a?(Hash) &&
attrs['id'].present? && attrs['id'].present? &&
attrs['name'].present? attrs['name'].present?
result.push(attrs) result.push(attrs)
end end
result result
end end
end end
private private
def normalize_data def normalize_data
@data = ::JSON.parse(@data) if @data.is_a?(String) @data = ::JSON.parse(@data) if @data.is_a?(String)
@data = @data.with_indifferent_access @data = @data.with_indifferent_access
end end
def prepare_data def prepare_data
@data[:steps].each do |step| @data[:steps].each do |step|
if step[:raw_description] if step[:raw_description]
@ -90,25 +90,25 @@ class CustomWizard::Template
end end
end end
end end
def validate_data def validate_data
validator = CustomWizard::TemplateValidator.new(@data, @opts) validator = CustomWizard::TemplateValidator.new(@data, @opts)
validator.perform validator.perform
add_errors_from(validator) add_errors_from(validator)
end end
def schedule_save_jobs def schedule_save_jobs
if @data[:after_time] && @data[:after_time_scheduled] if @data[:after_time] && @data[:after_time_scheduled]
wizard_id = @data[:id] wizard_id = @data[:id]
old_data = CustomWizard::Template.find(data[:id]) old_data = CustomWizard::Template.find(data[:id])
begin begin
enqueue_wizard_at = Time.parse(@data[:after_time_scheduled]).utc enqueue_wizard_at = Time.parse(@data[:after_time_scheduled]).utc
rescue ArgumentError rescue ArgumentError
errors.add :validation, I18n.t("wizard.validation.after_time") errors.add :validation, I18n.t("wizard.validation.after_time")
raise ActiveRecord::Rollback.new raise ActiveRecord::Rollback.new
end end
if enqueue_wizard_at if enqueue_wizard_at
Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id) Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id)
Jobs.enqueue_at(enqueue_wizard_at, :set_after_time_wizard, wizard_id: wizard_id) Jobs.enqueue_at(enqueue_wizard_at, :set_after_time_wizard, wizard_id: wizard_id)
@ -118,4 +118,4 @@ class CustomWizard::Template
end end
end end
end end
end end

Datei anzeigen

@ -1,42 +1,43 @@
# frozen_string_literal: true
class CustomWizard::TemplateValidator class CustomWizard::TemplateValidator
include HasErrors include HasErrors
include ActiveModel::Model include ActiveModel::Model
def initialize(data, opts={}) def initialize(data, opts = {})
@data = data @data = data
@opts = opts @opts = opts
end end
def perform def perform
data = @data data = @data
check_id(data, :wizard) check_id(data, :wizard)
check_required(data, :wizard) check_required(data, :wizard)
validate_after_time validate_after_time
data[:steps].each do |step| data[:steps].each do |step|
check_required(step, :step) check_required(step, :step)
if data[:fields].present? if data[:fields].present?
data[:fields].each do |field| data[:fields].each do |field|
check_required(field, :field) check_required(field, :field)
end end
end end
end end
if data[:actions].present? if data[:actions].present?
data[:actions].each do |action| data[:actions].each do |action|
check_required(action, :action) check_required(action, :action)
end end
end end
if errors.any? if errors.any?
false false
else else
true true
end end
end end
def self.required def self.required
{ {
wizard: ['id', 'name', 'steps'], wizard: ['id', 'name', 'steps'],
@ -45,13 +46,13 @@ class CustomWizard::TemplateValidator
action: ['id', 'type'] action: ['id', 'type']
} }
end end
private private
def check_required(object, type) def check_required(object, type)
CustomWizard::TemplateValidator.required[type].each do |property| CustomWizard::TemplateValidator.required[type].each do |property|
if object[property].blank? if object[property].blank?
errors.add :base, I18n.t("wizard.validation.required", property: property) errors.add :base, I18n.t("wizard.validation.required", property: property)
end end
end end
end end
@ -61,14 +62,14 @@ class CustomWizard::TemplateValidator
errors.add :base, I18n.t("wizard.validation.conflict", wizard_id: object[:id]) errors.add :base, I18n.t("wizard.validation.conflict", wizard_id: object[:id])
end end
end end
def validate_after_time def validate_after_time
return unless @data[:after_time] return unless @data[:after_time]
wizard = CustomWizard::Wizard.create(@data[:id]) if !@opts[:create] wizard = CustomWizard::Wizard.create(@data[:id]) if !@opts[:create]
current_time = wizard.present? ? wizard.after_time_scheduled : nil current_time = wizard.present? ? wizard.after_time_scheduled : nil
new_time = @data[:after_time_scheduled] new_time = @data[:after_time_scheduled]
begin begin
active_time = Time.parse(new_time.present? ? new_time : current_time).utc active_time = Time.parse(new_time.present? ? new_time : current_time).utc
rescue ArgumentError rescue ArgumentError
@ -79,4 +80,4 @@ class CustomWizard::TemplateValidator
errors.add :base, I18n.t("wizard.validation.after_time") errors.add :base, I18n.t("wizard.validation.after_time")
end end
end end
end end

Datei anzeigen

@ -1,21 +1,22 @@
# frozen_string_literal: true
require 'addressable/uri' require 'addressable/uri'
class ::CustomWizard::UpdateValidator class ::CustomWizard::UpdateValidator
attr_reader :updater attr_reader :updater
def initialize(updater) def initialize(updater)
@updater = updater @updater = updater
end end
def perform def perform
updater.step.fields.each do |field| updater.step.fields.each do |field|
validate_field(field) validate_field(field)
end end
end end
def validate_field(field) def validate_field(field)
return if field.type == 'text_only' return if field.type == 'text_only'
field_id = field.id.to_s field_id = field.id.to_s
value = @updater.submission[field_id] value = @updater.submission[field_id]
min_length = false min_length = false
@ -26,7 +27,7 @@ class ::CustomWizard::UpdateValidator
max_length = field.max_length if is_text_type(field) max_length = field.max_length if is_text_type(field)
file_types = field.file_types file_types = field.file_types
format = field.format format = field.format
if required && !value if required && !value
@updater.errors.add(field_id, I18n.t('wizard.field.required', label: label)) @updater.errors.add(field_id, I18n.t('wizard.field.required', label: label))
end end
@ -46,26 +47,26 @@ class ::CustomWizard::UpdateValidator
if type === 'checkbox' if type === 'checkbox'
@updater.submission[field_id] = standardise_boolean(value) @updater.submission[field_id] = standardise_boolean(value)
end end
if type === 'upload' && value.present? && !validate_file_type(value, file_types) 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)) @updater.errors.add(field_id, I18n.t('wizard.field.invalid_file', label: label, types: file_types))
end end
if ['date', 'date_time'].include?(type) && value.present? && !validate_date(value) if ['date', 'date_time'].include?(type) && value.present? && !validate_date(value)
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_date')) @updater.errors.add(field_id, I18n.t('wizard.field.invalid_date'))
end end
if type === 'time' && value.present? && !validate_time(value) if type === 'time' && value.present? && !validate_time(value)
@updater.errors.add(field_id, I18n.t('wizard.field.invalid_time')) @updater.errors.add(field_id, I18n.t('wizard.field.invalid_time'))
end end
self.class.field_validators.each do |validator| self.class.field_validators.each do |validator|
if type === validator[:type] if type === validator[:type]
validator[:block].call(field, value, @updater) validator[:block].call(field, value, @updater)
end end
end end
end end
def self.sorted_field_validators def self.sorted_field_validators
@sorted_field_validators ||= [] @sorted_field_validators ||= []
end end
@ -78,15 +79,15 @@ class ::CustomWizard::UpdateValidator
sorted_field_validators << { priority: priority, type: type, block: block } sorted_field_validators << { priority: priority, type: type, block: block }
@sorted_field_validators.sort_by! { |h| -h[:priority] } @sorted_field_validators.sort_by! { |h| -h[:priority] }
end end
private private
def validate_file_type(value, file_types) def validate_file_type(value, file_types)
file_types.split(',') file_types.split(',')
.map { |t| t.gsub('.', '') } .map { |t| t.gsub('.', '') }
.include?(File.extname(value['original_filename'])[1..-1]) .include?(File.extname(value['original_filename'])[1..-1])
end end
def validate_date(value) def validate_date(value)
begin begin
Date.parse(value) Date.parse(value)
@ -95,7 +96,7 @@ class ::CustomWizard::UpdateValidator
false false
end end
end end
def validate_time(value) def validate_time(value)
begin begin
Time.parse(value) Time.parse(value)
@ -112,17 +113,17 @@ class ::CustomWizard::UpdateValidator
def is_url_type(field) def is_url_type(field)
['url'].include? field.type ['url'].include? field.type
end end
SCHEMES ||= %w(http https) SCHEMES ||= %w(http https)
def check_if_url(url) def check_if_url(url)
parsed = Addressable::URI.parse(url) or return false parsed = Addressable::URI.parse(url) or return false
SCHEMES.include?(parsed.scheme) SCHEMES.include?(parsed.scheme)
rescue Addressable::URI::InvalidURIError rescue Addressable::URI::InvalidURIError
false false
end end
def standardise_boolean(value) def standardise_boolean(value)
ActiveRecord::Type::Boolean.new.cast(value) ActiveRecord::Type::Boolean.new.cast(value)
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_dependency 'wizard/step' require_dependency 'wizard/step'
require_dependency 'wizard/field' require_dependency 'wizard/field'
require_dependency 'wizard/step_updater' require_dependency 'wizard/step_updater'
@ -29,10 +30,10 @@ class CustomWizard::Wizard
:user, :user,
:first_step :first_step
def initialize(attrs = {}, user=nil) def initialize(attrs = {}, user = nil)
@user = user @user = user
attrs = attrs.with_indifferent_access attrs = attrs.with_indifferent_access
@id = attrs['id'] @id = attrs['id']
@name = attrs['name'] @name = attrs['name']
@background = attrs['background'] @background = attrs['background']
@ -48,21 +49,21 @@ class CustomWizard::Wizard
@needs_categories = false @needs_categories = false
@needs_groups = false @needs_groups = false
@theme_id = attrs['theme_id'] @theme_id = attrs['theme_id']
if attrs['theme'].present? if attrs['theme'].present?
theme = ::Theme.find_by(name: attrs['theme']) theme = ::Theme.find_by(name: attrs['theme'])
@theme_id = theme.id if theme @theme_id = theme.id if theme
end end
@first_step = nil @first_step = nil
@steps = [] @steps = []
if attrs['steps'].present? if attrs['steps'].present?
@step_ids = attrs['steps'].map { |s| s['id'] } @step_ids = attrs['steps'].map { |s| s['id'] }
end end
@actions = [] @actions = []
end end
def cast_bool(val) def cast_bool(val)
val.nil? ? false : ActiveRecord::Type::Boolean.new.cast(val) val.nil? ? false : ActiveRecord::Type::Boolean.new.cast(val)
end end
@ -73,12 +74,12 @@ class CustomWizard::Wizard
def append_step(step) def append_step(step)
step = create_step(step) if step.is_a?(String) step = create_step(step) if step.is_a?(String)
yield step if block_given? yield step if block_given?
last_step = steps.last last_step = steps.last
steps << step steps << step
if steps.size == 1 if steps.size == 1
@first_step = step @first_step = step
step.index = 0 step.index = 0
@ -133,7 +134,7 @@ class CustomWizard::Wizard
def completed? def completed?
return nil if !user return nil if !user
history = ::UserHistory.where( history = ::UserHistory.where(
acting_user_id: user.id, acting_user_id: user.id,
action: ::UserHistory.actions[:custom_wizard_step], action: ::UserHistory.actions[:custom_wizard_step],
@ -143,7 +144,7 @@ class CustomWizard::Wizard
if after_time if after_time
history = history.where("updated_at > ?", after_time_scheduled) history = history.where("updated_at > ?", after_time_scheduled)
end end
completed = history.distinct.order(:subject).pluck(:subject) completed = history.distinct.order(:subject).pluck(:subject)
(step_ids - completed).empty? (step_ids - completed).empty?
end end
@ -151,7 +152,7 @@ class CustomWizard::Wizard
def permitted? def permitted?
return false unless user return false unless user
return true if user.admin? || permitted.blank? return true if user.admin? || permitted.blank?
mapper = CustomWizard::Mapper.new( mapper = CustomWizard::Mapper.new(
inputs: permitted, inputs: permitted,
user: user, user: user,
@ -160,9 +161,9 @@ class CustomWizard::Wizard
multiple: true multiple: true
} }
).perform ).perform
return true if mapper.blank? return true if mapper.blank?
mapper.all? do |m| mapper.all? do |m|
if m[:type] === 'assignment' if m[:type] === 'assignment'
GroupUser.exists?(group_id: m[:result], user_id: user.id) GroupUser.exists?(group_id: m[:result], user_id: user.id)
@ -173,11 +174,11 @@ class CustomWizard::Wizard
end end
end end
end end
def can_access? def can_access?
return false unless user return false unless user
return true if user.admin return true if user.admin
return permitted? && (multiple_submissions || !completed?) permitted? && (multiple_submissions || !completed?)
end end
def reset def reset
@ -188,19 +189,19 @@ class CustomWizard::Wizard
subject: "reset" subject: "reset"
) )
end end
def categories def categories
@categories ||= ::Site.new(Guardian.new(user)).categories @categories ||= ::Site.new(Guardian.new(user)).categories
end end
def groups def groups
@groups ||= ::Site.new(Guardian.new(user)).groups @groups ||= ::Site.new(Guardian.new(user)).groups
end end
def submissions def submissions
Array.wrap(PluginStore.get("#{id}_submissions", user.id)) Array.wrap(PluginStore.get("#{id}_submissions", user.id))
end end
def current_submission def current_submission
if submissions.present? && !submissions.last.key?("submitted_at") if submissions.present? && !submissions.last.key?("submitted_at")
submissions.last submissions.last
@ -208,19 +209,19 @@ class CustomWizard::Wizard
nil nil
end end
end end
def set_submissions(submissions) def set_submissions(submissions)
PluginStore.set("#{id}_submissions", user.id, Array.wrap(submissions)) PluginStore.set("#{id}_submissions", user.id, Array.wrap(submissions))
end end
def self.submissions(wizard_id, user) def self.submissions(wizard_id, user)
new({ id: wizard_id }, user).submissions new({ id: wizard_id }, user).submissions
end end
def self.set_submissions(wizard_id, user, submissions) def self.set_submissions(wizard_id, user, submissions)
new({ id: wizard_id }, user).set_submissions(submissions) new({ id: wizard_id }, user).set_submissions(submissions)
end end
def self.create(wizard_id, user = nil) def self.create(wizard_id, user = nil)
if template = CustomWizard::Template.find(wizard_id) if template = CustomWizard::Template.find(wizard_id)
new(template.to_h, user) new(template.to_h, user)
@ -228,10 +229,10 @@ class CustomWizard::Wizard
false false
end end
end end
def self.list(user, template_opts: {}, not_completed: false) def self.list(user, template_opts: {}, not_completed: false)
return [] unless user return [] unless user
CustomWizard::Template.list(template_opts).reduce([]) do |result, template| CustomWizard::Template.list(template_opts).reduce([]) do |result, template|
wizard = new(template, user) wizard = new(template, user)
result.push(wizard) if wizard.can_access? && ( result.push(wizard) if wizard.can_access? && (
@ -279,7 +280,7 @@ class CustomWizard::Wizard
def self.set_wizard_redirect(wizard_id, user) def self.set_wizard_redirect(wizard_id, user)
wizard = self.create(wizard_id, user) wizard = self.create(wizard_id, user)
if wizard.permitted? if wizard.permitted?
user.custom_fields['redirect_to_wizard'] = wizard_id user.custom_fields['redirect_to_wizard'] = wizard_id
user.save_custom_fields(true) user.save_custom_fields(true)

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
# name: discourse-custom-wizard # name: discourse-custom-wizard
# about: Create custom wizards # about: Create custom wizards
# version: 0.7.0 # version: 0.7.0
@ -95,7 +96,7 @@ after_initialize do
].each do |path| ].each do |path|
load File.expand_path(path, __FILE__) load File.expand_path(path, __FILE__)
end end
add_class_method(:wizard, :user_requires_completion?) do |user| add_class_method(:wizard, :user_requires_completion?) do |user|
wizard_result = self.new(user).requires_completion? wizard_result = self.new(user).requires_completion?
return wizard_result if wizard_result return wizard_result if wizard_result
@ -114,7 +115,7 @@ after_initialize do
!!custom_redirect !!custom_redirect
end end
add_to_class(:users_controller, :wizard_path) do add_to_class(:users_controller, :wizard_path) do
if custom_wizard_redirect = current_user.custom_fields['redirect_to_wizard'] if custom_wizard_redirect = current_user.custom_fields['redirect_to_wizard']
"#{Discourse.base_url}/w/#{custom_wizard_redirect.dasherize}" "#{Discourse.base_url}/w/#{custom_wizard_redirect.dasherize}"
@ -132,13 +133,13 @@ after_initialize do
CustomWizard::Wizard.set_wizard_redirect(wizard.id, user) CustomWizard::Wizard.set_wizard_redirect(wizard.id, user)
end end
end end
add_to_class(:application_controller, :redirect_to_wizard_if_required) do add_to_class(:application_controller, :redirect_to_wizard_if_required) do
wizard_id = current_user.custom_fields['redirect_to_wizard'] wizard_id = current_user.custom_fields['redirect_to_wizard']
@excluded_routes ||= SiteSetting.wizard_redirect_exclude_paths.split('|') + ['/w/'] @excluded_routes ||= SiteSetting.wizard_redirect_exclude_paths.split('|') + ['/w/']
url = request.referer || request.original_url url = request.referer || request.original_url
if request.format === 'text/html' && !@excluded_routes.any? {|str| /#{str}/ =~ url} && wizard_id if request.format === 'text/html' && !@excluded_routes.any? { |str| /#{str}/ =~ url } && wizard_id
if request.referer !~ /\/w\// && request.referer !~ /\/invites\// if request.referer !~ /\/w\// && request.referer !~ /\/invites\//
CustomWizard::Wizard.set_submission_redirect(current_user, wizard_id, request.referer) CustomWizard::Wizard.set_submission_redirect(current_user, wizard_id, request.referer)
end end
@ -147,37 +148,37 @@ after_initialize do
end end
end end
end end
add_to_serializer(:site, :include_wizard_required?) do add_to_serializer(:site, :include_wizard_required?) do
scope.is_admin? && Wizard.new(scope.user).requires_completion? scope.is_admin? && Wizard.new(scope.user).requires_completion?
end end
add_to_serializer(:site, :complete_custom_wizard) do add_to_serializer(:site, :complete_custom_wizard) do
if scope.user && requires_completion = CustomWizard::Wizard.prompt_completion(scope.user) if scope.user && requires_completion = CustomWizard::Wizard.prompt_completion(scope.user)
requires_completion.map {|w| { name: w[:name], url: "/w/#{w[:id]}"} } requires_completion.map { |w| { name: w[:name], url: "/w/#{w[:id]}" } }
end end
end end
add_to_serializer(:site, :include_complete_custom_wizard?) do add_to_serializer(:site, :include_complete_custom_wizard?) do
complete_custom_wizard.present? complete_custom_wizard.present?
end end
add_model_callback(:application_controller, :before_action) do add_model_callback(:application_controller, :before_action) do
redirect_to_wizard_if_required if current_user redirect_to_wizard_if_required if current_user
end end
::ExtraLocalesController.prepend ExtraLocalesControllerCustomWizard ::ExtraLocalesController.prepend ExtraLocalesControllerCustomWizard
::InvitesController.prepend InvitesControllerCustomWizard ::InvitesController.prepend InvitesControllerCustomWizard
::UsersController.prepend CustomWizardUsersController ::UsersController.prepend CustomWizardUsersController
::Wizard::Field.prepend CustomWizardFieldExtension ::Wizard::Field.prepend CustomWizardFieldExtension
::Wizard::Step.prepend CustomWizardStepExtension ::Wizard::Step.prepend CustomWizardStepExtension
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"
DiscoursePluginRegistry.register_asset(full_path, {}, "wizard_custom") DiscoursePluginRegistry.register_asset(full_path, {}, "wizard_custom")
Stylesheet::Importer.register_import("wizard_custom") do Stylesheet::Importer.register_import("wizard_custom") do
import_files(DiscoursePluginRegistry.stylesheets["wizard_custom"]) import_files(DiscoursePluginRegistry.stylesheets["wizard_custom"])
end end
CustomWizard::CustomField::CLASSES.keys.each do |klass| CustomWizard::CustomField::CLASSES.keys.each do |klass|
add_model_callback(klass, :after_initialize) do add_model_callback(klass, :after_initialize) do
if CustomWizard::CustomField.enabled? if CustomWizard::CustomField.enabled?
@ -189,10 +190,10 @@ after_initialize do
end end
end end
end end
klass.to_s.classify.constantize.singleton_class.prepend CustomWizardCustomFieldPreloader klass.to_s.classify.constantize.singleton_class.prepend CustomWizardCustomFieldPreloader
end end
CustomWizard::CustomField.serializers.each do |serializer_klass| CustomWizard::CustomField.serializers.each do |serializer_klass|
"#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerializer "#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerializer
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::Api::AuthorizationSerializer < ::ApplicationSerializer class CustomWizard::Api::AuthorizationSerializer < ::ApplicationSerializer
attributes :auth_type, attributes :auth_type,
:auth_url, :auth_url,

Datei anzeigen

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

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::Api::EndpointSerializer < ::ApplicationSerializer class CustomWizard::Api::EndpointSerializer < ::ApplicationSerializer
attributes :id, attributes :id,
:name, :name,

Datei anzeigen

@ -1,12 +1,13 @@
class CustomWizard::Api::LogSerializer < ::ApplicationSerializer # frozen_string_literal: true
attributes :log_id, class CustomWizard::Api::LogSerializer < ::ApplicationSerializer
:time, attributes :log_id,
:status, :time,
:url, :status,
:error, :url,
:user_id, :error,
:username, :user_id,
:userpath, :username,
:name, :userpath,
:avatar_template :name,
end :avatar_template
end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::ApiSerializer < ::ApplicationSerializer class CustomWizard::ApiSerializer < ::ApplicationSerializer
attributes :name, attributes :name,
:title, :title,

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::BasicApiSerializer < ::ApplicationSerializer class CustomWizard::BasicApiSerializer < ::ApplicationSerializer
attributes :name, attributes :name,
:title, :title,

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::BasicWizardSerializer < ::ApplicationSerializer class CustomWizard::BasicWizardSerializer < ::ApplicationSerializer
attributes :id, :name attributes :id, :name
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::CustomFieldSerializer < ApplicationSerializer class CustomWizard::CustomFieldSerializer < ApplicationSerializer
attributes :id, :klass, :name, :type, :serializers attributes :id, :klass, :name, :type, :serializers
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::LogSerializer < ApplicationSerializer class CustomWizard::LogSerializer < ApplicationSerializer
attributes :message, :date attributes :message, :date
end end

Datei anzeigen

@ -1,2 +1,3 @@
# frozen_string_literal: true
class ::CustomWizard::RealtimeValidation::SimilarTopicsSerializer < ::SimilarTopicSerializer class ::CustomWizard::RealtimeValidation::SimilarTopicsSerializer < ::SimilarTopicSerializer
end end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::FieldSerializer < ::WizardFieldSerializer class CustomWizard::FieldSerializer < ::WizardFieldSerializer
attributes :image, attributes :image,
:file_types, :file_types,
:format, :format,
@ -38,23 +38,23 @@ class CustomWizard::FieldSerializer < ::WizardFieldSerializer
def file_types def file_types
object.file_types object.file_types
end end
def format def format
object.format object.format
end end
def limit def limit
object.limit object.limit
end end
def property def property
object.property object.property
end end
def content def content
object.content object.content
end end
def include_choices? def include_choices?
object.choices.present? object.choices.present?
end end
@ -81,4 +81,4 @@ class CustomWizard::FieldSerializer < ::WizardFieldSerializer
def number def number
object.number object.number
end end
end end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
attributes :start, attributes :start,
:background, :background,
:theme_id, :theme_id,
@ -9,7 +9,7 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
:required, :required,
:permitted, :permitted,
:uncategorized_category_id :uncategorized_category_id
has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects
has_one :user, serializer: ::BasicUserSerializer, embed: :objects has_one :user, serializer: ::BasicUserSerializer, embed: :objects
has_many :categories, serializer: ::BasicCategorySerializer, embed: :objects has_many :categories, serializer: ::BasicCategorySerializer, embed: :objects
@ -28,7 +28,7 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
def permitted def permitted
object.permitted? object.permitted?
end end
def start def start
object.start.id object.start.id
end end
@ -40,20 +40,20 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
def include_steps? def include_steps?
!include_completed? !include_completed?
end end
def include_categories? def include_categories?
object.needs_categories object.needs_categories
end end
def include_groups? def include_groups?
object.needs_groups object.needs_groups
end end
def uncategorized_category_id def uncategorized_category_id
SiteSetting.uncategorized_category_id SiteSetting.uncategorized_category_id
end end
def include_uncategorized_category_id? def include_uncategorized_category_id?
object.needs_categories object.needs_categories
end end
end end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::StepSerializer < ::WizardStepSerializer class CustomWizard::StepSerializer < ::WizardStepSerializer
attributes :permitted, :permitted_message attributes :permitted, :permitted_message
has_many :fields, serializer: ::CustomWizard::FieldSerializer, embed: :objects has_many :fields, serializer: ::CustomWizard::FieldSerializer, embed: :objects
@ -18,8 +18,8 @@ class CustomWizard::StepSerializer < ::WizardStepSerializer
def permitted def permitted
object.permitted object.permitted
end end
def permitted_message def permitted_message
object.permitted_message object.permitted_message
end end
end end

Datei anzeigen

@ -4,13 +4,13 @@ describe CustomWizard::Action do
fab!(:user) { Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com", trust_level: TrustLevel[2]) } fab!(:user) { Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com", trust_level: TrustLevel[2]) }
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') } fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') }
fab!(:group) { Fabricate(:group) } fab!(:group) { Fabricate(:group) }
let(:open_composer) { let(:open_composer) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/open_composer.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/open_composer.json"
).read) ).read)
} }
before do before do
Group.refresh_automatic_group!(:trust_level_2) Group.refresh_automatic_group!(:trust_level_2)
CustomWizard::Template.save( CustomWizard::Template.save(
@ -20,7 +20,7 @@ describe CustomWizard::Action do
skip_jobs: true) skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
context 'creating a topic' do context 'creating a topic' do
it "works" do it "works" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
@ -33,7 +33,7 @@ describe CustomWizard::Action do
wizard.create_updater(wizard.steps.last.id, wizard.create_updater(wizard.steps.last.id,
step_3_field_3: category.id step_3_field_3: category.id
).update ).update
topic = Topic.where( topic = Topic.where(
title: "Topic Title", title: "Topic Title",
category_id: category.id category_id: category.id
@ -44,7 +44,7 @@ describe CustomWizard::Action do
raw: "topic body" raw: "topic body"
).exists?).to eq(true) ).exists?).to eq(true)
end end
it "fails silently without basic topic inputs" do it "fails silently without basic topic inputs" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater( wizard.create_updater(
@ -54,7 +54,7 @@ describe CustomWizard::Action do
wizard.create_updater(wizard.steps.second.id, {}).update wizard.create_updater(wizard.steps.second.id, {}).update
updater = wizard.create_updater(wizard.steps.last.id, {}) updater = wizard.create_updater(wizard.steps.last.id, {})
updater.update updater.update
expect(updater.success?).to eq(true) expect(updater.success?).to eq(true)
expect(UserHistory.where( expect(UserHistory.where(
acting_user_id: user.id, acting_user_id: user.id,
@ -66,29 +66,29 @@ describe CustomWizard::Action do
).exists?).to eq(false) ).exists?).to eq(false)
end end
end end
it 'sends a message' do it 'sends a message' do
User.create(username: 'angus1', email: "angus1@email.com") User.create(username: 'angus1', email: "angus1@email.com")
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, {}).update wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
topic = Topic.where( topic = Topic.where(
archetype: Archetype.private_message, archetype: Archetype.private_message,
title: "Message title" title: "Message title"
) )
post = Post.where( post = Post.where(
topic_id: topic.pluck(:id), topic_id: topic.pluck(:id),
raw: "I will interpolate some wizard fields" raw: "I will interpolate some wizard fields"
) )
expect(topic.exists?).to eq(true) expect(topic.exists?).to eq(true)
expect(topic.first.topic_allowed_users.first.user.username).to eq('angus1') expect(topic.first.topic_allowed_users.first.user.username).to eq('angus1')
expect(post.exists?).to eq(true) expect(post.exists?).to eq(true)
end end
it 'updates a profile' do it 'updates a profile' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
upload = Upload.create!( upload = Upload.create!(
@ -104,28 +104,28 @@ describe CustomWizard::Action do
).update ).update
expect(user.profile_background_upload.id).to eq(upload.id) expect(user.profile_background_upload.id).to eq(upload.id)
end end
context "open composer" do context "open composer" do
it 'works' do it 'works' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
updater = wizard.create_updater(wizard.steps[1].id, {}) updater = wizard.create_updater(wizard.steps[1].id, {})
updater.update updater.update
category = Category.find_by(id: wizard.current_submission['action_8']) category = Category.find_by(id: wizard.current_submission['action_8'])
expect(updater.result[:redirect_on_next]).to eq( expect(updater.result[:redirect_on_next]).to eq(
"/new-topic?title=Title%20of%20the%20composer%20topic&body=I%20am%20interpolating%20some%20user%20fields%20Angus%20angus%20angus%40email.com&category_id=#{category.id}&tags=tag1" "/new-topic?title=Title%20of%20the%20composer%20topic&body=I%20am%20interpolating%20some%20user%20fields%20Angus%20angus%20angus%40email.com&category_id=#{category.id}&tags=tag1"
) )
end end
it 'encodes special characters in the title and body' do it 'encodes special characters in the title and body' do
open_composer['title'][0]['output'] = "Title that's special $" open_composer['title'][0]['output'] = "Title that's special $"
open_composer['post_template'] = "Body & more body & more body" open_composer['post_template'] = "Body & more body & more body"
wizard = CustomWizard::Wizard.new(@template, user) wizard = CustomWizard::Wizard.new(@template, user)
action = CustomWizard::Action.new( action = CustomWizard::Action.new(
wizard: wizard, wizard: wizard,
action: open_composer, action: open_composer,
@ -133,30 +133,30 @@ describe CustomWizard::Action do
data: {} data: {}
) )
action.perform action.perform
expect(action.result.success?).to eq(true) expect(action.result.success?).to eq(true)
decoded_output = CGI.parse(URI.parse(action.result.output).query) decoded_output = CGI.parse(URI.parse(action.result.output).query)
expect(decoded_output['title'][0]).to eq("Title that's special $") expect(decoded_output['title'][0]).to eq("Title that's special $")
expect(decoded_output['body'][0]).to eq("Body & more body & more body") expect(decoded_output['body'][0]).to eq("Body & more body & more body")
end end
end end
it 'creates a category' do it 'creates a category' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
expect(Category.where(id: wizard.current_submission['action_8']).exists?).to eq(true) expect(Category.where(id: wizard.current_submission['action_8']).exists?).to eq(true)
end end
it 'creates a group' do it 'creates a group' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
step_id = wizard.steps[0].id step_id = wizard.steps[0].id
updater = wizard.create_updater(step_id, step_1_field_1: "Text input").update updater = wizard.create_updater(step_id, step_1_field_1: "Text input").update
expect(Group.where(name: wizard.current_submission['action_9']).exists?).to eq(true) expect(Group.where(name: wizard.current_submission['action_9']).exists?).to eq(true)
end end
it 'adds a user to a group' do it 'adds a user to a group' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
step_id = wizard.steps[0].id step_id = wizard.steps[0].id
@ -164,7 +164,7 @@ describe CustomWizard::Action do
group = Group.find_by(name: wizard.current_submission['action_9']) group = Group.find_by(name: wizard.current_submission['action_9'])
expect(group.users.first.username).to eq('angus') expect(group.users.first.username).to eq('angus')
end end
it 'watches categories' do it 'watches categories' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
@ -178,7 +178,7 @@ describe CustomWizard::Action do
user_id: user.id user_id: user.id
).first.notification_level).to eq(0) ).first.notification_level).to eq(0)
end end
it 're-routes a user' do it 're-routes a user' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
updater = wizard.create_updater(wizard.steps.last.id, {}) updater = wizard.create_updater(wizard.steps.last.id, {})

Datei anzeigen

@ -1,5 +1,3 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Builder do describe CustomWizard::Builder do
@ -9,31 +7,31 @@ describe CustomWizard::Builder do
username: 'angus', username: 'angus',
email: "angus@email.com", email: "angus@email.com",
trust_level: TrustLevel[3] trust_level: TrustLevel[3]
) )
} }
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:category1) { Fabricate(:category, name: 'cat1') } fab!(:category1) { Fabricate(:category, name: 'cat1') }
fab!(:category2) { Fabricate(:category, name: 'cat2') } fab!(:category2) { Fabricate(:category, name: 'cat2') }
fab!(:group) { Fabricate(:group) } fab!(:group) { Fabricate(:group) }
let(:required_data_json) { let(:required_data_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/required_data.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/required_data.json"
).read) ).read)
} }
let(:permitted_json) { let(:permitted_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json"
).read) ).read)
} }
let(:permitted_param_json) { let(:permitted_param_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/permitted_params.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/permitted_params.json"
).read) ).read)
} }
before do before do
Group.refresh_automatic_group!(:trust_level_3) Group.refresh_automatic_group!(:trust_level_3)
CustomWizard::Template.save( CustomWizard::Template.save(
@ -43,51 +41,51 @@ describe CustomWizard::Builder do
skip_jobs: true) skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
context 'disabled' do context 'disabled' do
before do before do
SiteSetting.custom_wizard_enabled = false SiteSetting.custom_wizard_enabled = false
end end
it "returns nil" do it "returns nil" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
).to eq(nil) ).to eq(nil)
end end
end end
context 'enabled' do context 'enabled' do
before do before do
SiteSetting.custom_wizard_enabled = true SiteSetting.custom_wizard_enabled = true
end end
it "returns wizard metadata" do it "returns wizard metadata" do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
expect(wizard.id).to eq("super_mega_fun_wizard") expect(wizard.id).to eq("super_mega_fun_wizard")
expect(wizard.name).to eq("Super Mega Fun Wizard") expect(wizard.name).to eq("Super Mega Fun Wizard")
expect(wizard.background).to eq("#333333") expect(wizard.background).to eq("#333333")
end end
it "returns steps" do it "returns steps" do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.steps.length .steps.length
).to eq(3) ).to eq(3)
end end
context "with multiple submissions disabled" do context "with multiple submissions disabled" do
before do before do
@template[:multiple_submissions] = false @template[:multiple_submissions] = false
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'returns steps if user has not completed it' do it 'returns steps if user has not completed it' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.steps.length .steps.length
).to eq(3) ).to eq(3)
end end
it 'returns no steps if user has completed it' do it 'returns no steps if user has completed it' do
@template[:steps].each do |step| @template[:steps].each do |step|
UserHistory.create!( UserHistory.create!(
@ -100,62 +98,62 @@ describe CustomWizard::Builder do
) )
) )
end end
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.steps.length .steps.length
).to eq(0) ).to eq(0)
end end
end end
context "with restricted permissions" do context "with restricted permissions" do
before do before do
@template[:permitted] = permitted_json["permitted"] @template[:permitted] = permitted_json["permitted"]
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'is not permitted if user is not in permitted group' do it 'is not permitted if user is not in permitted group' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.permitted? .permitted?
).to eq(false) ).to eq(false)
end end
it 'user cannot access if not permitted' do it 'user cannot access if not permitted' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.can_access? .can_access?
).to eq(false) ).to eq(false)
end end
it 'returns wizard metadata if user is not permitted' do it 'returns wizard metadata if user is not permitted' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.name .name
).to eq("Super Mega Fun Wizard") ).to eq("Super Mega Fun Wizard")
end end
it 'returns no steps if user is not permitted' do it 'returns no steps if user is not permitted' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
.steps.length .steps.length
).to eq(0) ).to eq(0)
end end
it 'is permitted if user is in permitted group' do it 'is permitted if user is in permitted group' do
expect( expect(
CustomWizard::Builder.new(@template[:id], trusted_user).build CustomWizard::Builder.new(@template[:id], trusted_user).build
.permitted? .permitted?
).to eq(true) ).to eq(true)
end end
it 'user can access if permitted' do it 'user can access if permitted' do
expect( expect(
CustomWizard::Builder.new(@template[:id], trusted_user).build CustomWizard::Builder.new(@template[:id], trusted_user).build
.can_access? .can_access?
).to eq(true) ).to eq(true)
end end
it 'returns steps if user is permitted' do it 'returns steps if user is permitted' do
expect( expect(
CustomWizard::Builder.new(@template[:id], trusted_user).build CustomWizard::Builder.new(@template[:id], trusted_user).build
@ -163,7 +161,7 @@ describe CustomWizard::Builder do
).to eq(3) ).to eq(3)
end end
end end
it 'returns prefilled data' do it 'returns prefilled data' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
@ -172,13 +170,13 @@ describe CustomWizard::Builder do
.value .value
).to eq('I am prefilled') ).to eq('I am prefilled')
end end
context "user has partially completed" do context "user has partially completed" do
before do before do
wizard = CustomWizard::Wizard.new(@template, user) wizard = CustomWizard::Wizard.new(@template, user)
wizard.set_submissions(step_1_field_1: 'I am a user submission') wizard.set_submissions(step_1_field_1: 'I am a user submission')
end end
it 'returns saved submissions' do it 'returns saved submissions' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
@ -187,13 +185,13 @@ describe CustomWizard::Builder do
.value .value
).to eq('I am a user submission') ).to eq('I am a user submission')
end end
context "restart is enabled" do context "restart is enabled" do
before do before do
@template[:restart_on_revisit] = true @template[:restart_on_revisit] = true
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'does not return saved submissions' do it 'does not return saved submissions' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
@ -210,19 +208,19 @@ describe CustomWizard::Builder do
first_step = CustomWizard::Builder.new(@template[:id], user) first_step = CustomWizard::Builder.new(@template[:id], user)
.build(reset: true) .build(reset: true)
.steps.first .steps.first
expect(first_step.id).to eq("step_1") expect(first_step.id).to eq("step_1")
expect(first_step.title).to eq("Text") expect(first_step.title).to eq("Text")
expect(first_step.description).to eq("<p>Text inputs!</p>") expect(first_step.description).to eq("<p>Text inputs!</p>")
end end
context 'with required data' do context 'with required data' do
before do before do
@template[:steps][0][:required_data] = required_data_json['required_data'] @template[:steps][0][:required_data] = required_data_json['required_data']
@template[:steps][0][:required_data_message] = required_data_json['required_data_message'] @template[:steps][0][:required_data_message] = required_data_json['required_data_message']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'is not permitted if required data is not present' do it 'is not permitted if required data is not present' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
@ -230,7 +228,7 @@ describe CustomWizard::Builder do
.permitted .permitted
).to eq(false) ).to eq(false)
end end
it 'it shows required data message' do it 'it shows required data message' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user).build CustomWizard::Builder.new(@template[:id], user).build
@ -238,7 +236,7 @@ describe CustomWizard::Builder do
.permitted_message .permitted_message
).to eq("Missing required data") ).to eq("Missing required data")
end end
it 'is permitted if required data is present' do it 'is permitted if required data is present' do
CustomWizard::Wizard.set_submissions('super_mega_fun_wizard', user, CustomWizard::Wizard.set_submissions('super_mega_fun_wizard', user,
required_data: "required_value" required_data: "required_value"
@ -250,33 +248,33 @@ describe CustomWizard::Builder do
).to eq(true) ).to eq(true)
end end
end end
context "with permitted params" do context "with permitted params" do
before do before do
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params'] @template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'saves permitted params' do it 'saves permitted params' do
wizard = CustomWizard::Builder.new(@template[:id], user).build({}, wizard = CustomWizard::Builder.new(@template[:id], user).build({},
param: 'param_value' param: 'param_value'
) )
expect(wizard.current_submission['saved_param']).to eq('param_value') expect(wizard.current_submission['saved_param']).to eq('param_value')
end end
end end
end end
context 'building field' do context 'building field' do
it 'returns field metadata' do it 'returns field metadata' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
field = wizard.steps.first.fields.first field = wizard.steps.first.fields.first
expect(field.label).to eq("<p>Text</p>") expect(field.label).to eq("<p>Text</p>")
expect(field.type).to eq("text") expect(field.type).to eq("text")
expect(field.id).to eq("step_1_field_1") expect(field.id).to eq("step_1_field_1")
expect(field.min_length).to eq("3") expect(field.min_length).to eq("3")
end end
it 'returns all step fields' do it 'returns all step fields' do
expect( expect(
CustomWizard::Builder.new(@template[:id], user) CustomWizard::Builder.new(@template[:id], user)
@ -286,7 +284,7 @@ describe CustomWizard::Builder do
).to eq(4) ).to eq(4)
end end
end end
context 'on update' do context 'on update' do
def perform_update(step_id, submission) def perform_update(step_id, submission)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
@ -294,7 +292,7 @@ describe CustomWizard::Builder do
updater.update updater.update
updater updater
end end
it 'saves submissions' do it 'saves submissions' do
perform_update('step_1', step_1_field_1: 'Text input') perform_update('step_1', step_1_field_1: 'Text input')
expect( expect(
@ -302,13 +300,13 @@ describe CustomWizard::Builder do
.first['step_1_field_1'] .first['step_1_field_1']
).to eq('Text input') ).to eq('Text input')
end end
context 'save submissions disabled' do context 'save submissions disabled' do
before do before do
@template[:save_submissions] = false @template[:save_submissions] = false
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it "does not save submissions" do it "does not save submissions" do
perform_update('step_1', step_1_field_1: 'Text input') perform_update('step_1', step_1_field_1: 'Text input')
expect( expect(
@ -318,4 +316,4 @@ describe CustomWizard::Builder do
end end
end end
end end
end end

Datei anzeigen

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

Datei anzeigen

@ -3,17 +3,17 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::CustomField do describe CustomWizard::CustomField do
let(:custom_field_json) { let(:custom_field_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read) ).read)
} }
before do before do
CustomWizard::CustomField.invalidate_cache CustomWizard::CustomField.invalidate_cache
end end
it "saves custom field records" do it "saves custom field records" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
@ -23,38 +23,38 @@ describe CustomWizard::CustomField do
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
key = '#{custom_field.name}' AND key = '#{custom_field.name}' AND
value::jsonb = '#{field_json.except('name').to_json}'::jsonb value::jsonb = '#{field_json.except('name').to_json}'::jsonb
", ).exists? ",).exists?
).to eq(true) ).to eq(true)
end end
end end
it "updates existing custom field records" do it "updates existing custom field records" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
updated_field_json = custom_field_json['custom_fields'][0] updated_field_json = custom_field_json['custom_fields'][0]
updated_field_json['serializers'] = ["topic_view"] updated_field_json['serializers'] = ["topic_view"]
existing_field = CustomWizard::CustomField.find_by_name(updated_field_json["name"]) existing_field = CustomWizard::CustomField.find_by_name(updated_field_json["name"])
updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json) updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json)
expect(updated_field.save).to eq(true) expect(updated_field.save).to eq(true)
expect( expect(
PluginStoreRow.where(" PluginStoreRow.where("
plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND plugin_name = '#{CustomWizard::CustomField::NAMESPACE}' AND
key = '#{updated_field.name}' AND key = '#{updated_field.name}' AND
value::jsonb = '#{updated_field_json.except('name').to_json}'::jsonb value::jsonb = '#{updated_field_json.except('name').to_json}'::jsonb
", ).exists? ",).exists?
).to eq(true) ).to eq(true)
end end
context "validation" do context "validation" do
it "does not save with an unsupported class" do it "does not save with an unsupported class" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json['custom_fields'].first
invalid_field_json['klass'] = 'user' invalid_field_json['klass'] = 'user'
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
@ -67,14 +67,14 @@ describe CustomWizard::CustomField do
).exists? ).exists?
).to eq(false) ).to eq(false)
end end
it "does not save with an unsupported serializer" do it "does not save with an unsupported serializer" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json['custom_fields'].first
invalid_field_json['klass'] = 'category' invalid_field_json['klass'] = 'category'
invalid_field_json['serializers'] = ['category', 'site_category'] invalid_field_json['serializers'] = ['category', 'site_category']
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
@ -90,13 +90,13 @@ describe CustomWizard::CustomField do
).exists? ).exists?
).to eq(false) ).to eq(false)
end end
it "does not save with an unsupported type" do it "does not save with an unsupported type" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json['custom_fields'].first
invalid_field_json['type'] = 'bigint' invalid_field_json['type'] = 'bigint'
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
@ -109,13 +109,13 @@ describe CustomWizard::CustomField do
).exists? ).exists?
).to eq(false) ).to eq(false)
end end
it "does not save with a short field name" do it "does not save with a short field name" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json['custom_fields'].first
invalid_field_json['name'] = 'cf' invalid_field_json['name'] = 'cf'
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
@ -128,28 +128,28 @@ describe CustomWizard::CustomField do
).exists? ).exists?
).to eq(false) ).to eq(false)
end end
it "does not save with an existing name if new" do it "does not save with an existing name if new" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
first_field_json = custom_field_json['custom_fields'][0] first_field_json = custom_field_json['custom_fields'][0]
custom_field = CustomWizard::CustomField.new(nil, first_field_json) custom_field = CustomWizard::CustomField.new(nil, first_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.name_already_taken", name: "topic_field_1") I18n.t("wizard.custom_field.error.name_already_taken", name: "topic_field_1")
) )
end end
it "does not save with an invalid name" do it "does not save with an invalid name" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json['custom_fields'].first
invalid_field_json['name'] = ["invalid_name"] invalid_field_json['name'] = ["invalid_name"]
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
expect(custom_field.save).to eq(false) expect(custom_field.save).to eq(false)
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
@ -163,31 +163,31 @@ describe CustomWizard::CustomField do
).to eq(false) ).to eq(false)
end end
end end
context "lists" do context "lists" do
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
end end
it "lists saved custom field records" do it "lists saved custom field records" do
expect(CustomWizard::CustomField.list.length).to eq(4) expect(CustomWizard::CustomField.list.length).to eq(4)
end end
it "lists saved custom field records by attribute value" do it "lists saved custom field records by attribute value" do
expect(CustomWizard::CustomField.list_by(:klass, 'topic').length).to eq(1) expect(CustomWizard::CustomField.list_by(:klass, 'topic').length).to eq(1)
end end
end end
it "is enabled if there are custom fields" do it "is enabled if there are custom fields" do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
expect(CustomWizard::CustomField.enabled?).to eq(true) expect(CustomWizard::CustomField.enabled?).to eq(true)
end end
it "is not enabled if there are no custom fields" do it "is not enabled if there are no custom fields" do
expect(CustomWizard::CustomField.enabled?).to eq(false) expect(CustomWizard::CustomField.enabled?).to eq(false)
end end
end end

Datei anzeigen

@ -1,7 +1,8 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Field do describe CustomWizard::Field do
before do before do
CustomWizard::Field.register( CustomWizard::Field.register(
'location', 'location',
'discourse-locations', 'discourse-locations',
@ -11,20 +12,20 @@ describe CustomWizard::Field do
} }
) )
end end
it "registers custom field types" do it "registers custom field types" do
expect(CustomWizard::Field.types[:location].present?).to eq(true) expect(CustomWizard::Field.types[:location].present?).to eq(true)
end end
it "allows custom field types to set default attributes" do it "allows custom field types to set default attributes" do
expect( expect(
CustomWizard::Field.types[:location][:prefill] CustomWizard::Field.types[:location][:prefill]
).to eq({ "coordinates": [35.3082, 149.1244] }) ).to eq({ "coordinates": [35.3082, 149.1244] })
end end
it "registers custom field assets" do it "registers custom field assets" do
expect( expect(
CustomWizard::Field.require_assets['discourse-locations'] CustomWizard::Field.require_assets['discourse-locations']
).to eq(['components', 'helpers', 'lib', 'stylesheets', 'templates']) ).to eq(['components', 'helpers', 'lib', 'stylesheets', 'templates'])
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Log do describe CustomWizard::Log do
@ -6,22 +7,22 @@ describe CustomWizard::Log do
CustomWizard::Log.create("Second log message") CustomWizard::Log.create("Second log message")
CustomWizard::Log.create("Third log message") CustomWizard::Log.create("Third log message")
end end
it "creates logs" do it "creates logs" do
expect( expect(
CustomWizard::Log.list.length CustomWizard::Log.list.length
).to eq(3) ).to eq(3)
end end
it "lists logs by time created" do it "lists logs by time created" do
expect( expect(
CustomWizard::Log.list.first.message CustomWizard::Log.list.first.message
).to eq("Third log message") ).to eq("Third log message")
end end
it "paginates logs" do it "paginates logs" do
expect( expect(
CustomWizard::Log.list(0, 2).length CustomWizard::Log.list(0, 2).length
).to eq(2) ).to eq(2)
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Mapper do describe CustomWizard::Mapper do
@ -40,7 +41,7 @@ describe CustomWizard::Mapper do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/mapper/data.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/mapper/data.json"
).read) ).read)
} }
it "maps values" do it "maps values" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['assignment'], inputs: inputs['assignment'],
@ -48,7 +49,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq([13]) ).perform).to eq([13])
end end
it "maps associations" do it "maps associations" do
association = CustomWizard::Mapper.new( association = CustomWizard::Mapper.new(
inputs: inputs['association'], inputs: inputs['association'],
@ -58,7 +59,7 @@ describe CustomWizard::Mapper do
expect(association.length).to eq(3) expect(association.length).to eq(3)
expect(association.first[:value]).to eq("Choice 1") expect(association.first[:value]).to eq("Choice 1")
end end
context "conditional mapping" do context "conditional mapping" do
it "maps when the condition is met" do it "maps when the condition is met" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
@ -67,7 +68,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("true") ).perform).to eq("true")
end end
it "does not map when the condition is not met" do it "does not map when the condition is not met" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['conditional'], inputs: inputs['conditional'],
@ -75,7 +76,7 @@ describe CustomWizard::Mapper do
user: user2 user: user2
).perform).to eq(nil) ).perform).to eq(nil)
end end
it "maps when multiple conditions are met" do it "maps when multiple conditions are met" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['conditional_multiple_pairs'], inputs: inputs['conditional_multiple_pairs'],
@ -83,9 +84,11 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("true") ).perform).to eq("true")
end end
it "does not map when one of multiple conditions are not met" do it "does not map when one of multiple conditions are not met" do
user1.email = "angus@other-email.com" user1.email = "angus@other-email.com"
user1.save
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['conditional_multiple_pairs'], inputs: inputs['conditional_multiple_pairs'],
data: data, data: data,
@ -93,7 +96,7 @@ describe CustomWizard::Mapper do
).perform).to eq(nil) ).perform).to eq(nil)
end end
end end
it "validates valid data" do it "validates valid data" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['validation'], inputs: inputs['validation'],
@ -101,7 +104,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq(true) ).perform).to eq(true)
end end
it "does not validate invalid data" do it "does not validate invalid data" do
data["input_2"] = "value 3" data["input_2"] = "value 3"
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
@ -110,7 +113,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq(false) ).perform).to eq(false)
end end
it "maps text fields" do it "maps text fields" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['assignment_text'], inputs: inputs['assignment_text'],
@ -118,7 +121,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("Value") ).perform).to eq("Value")
end end
it "maps user fields" do it "maps user fields" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['assignment_user_field'], inputs: inputs['assignment_user_field'],
@ -126,7 +129,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("Angus") ).perform).to eq("Angus")
end end
it "maps user field options" do it "maps user field options" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['assignment_user_field_options'], inputs: inputs['assignment_user_field_options'],
@ -134,7 +137,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq(["a", "b", "c"]) ).perform).to eq(["a", "b", "c"])
end end
it "maps wizard fields" do it "maps wizard fields" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['assignment_wizard_field'], inputs: inputs['assignment_wizard_field'],
@ -142,7 +145,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("value 1") ).perform).to eq("value 1")
end end
it "maps wizard actions" do it "maps wizard actions" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['assignment_wizard_action'], inputs: inputs['assignment_wizard_action'],
@ -150,7 +153,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("value 2") ).perform).to eq("value 2")
end end
it "interpolates user fields" do it "interpolates user fields" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['interpolate_user_field'], inputs: inputs['interpolate_user_field'],
@ -158,7 +161,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("Name: Angus") ).perform).to eq("Name: Angus")
end end
it "interpolates wizard fields" do it "interpolates wizard fields" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['interpolate_wizard_field'], inputs: inputs['interpolate_wizard_field'],
@ -166,7 +169,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("Input 1: value 1") ).perform).to eq("Input 1: value 1")
end end
it "interpolates date" do it "interpolates date" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['interpolate_timestamp'], inputs: inputs['interpolate_timestamp'],
@ -174,7 +177,7 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}") ).perform).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}")
end end
it "handles greater than pairs" do it "handles greater than pairs" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['greater_than_pair'], inputs: inputs['greater_than_pair'],
@ -187,7 +190,7 @@ describe CustomWizard::Mapper do
user: user2 user: user2
).perform).to eq(false) ).perform).to eq(false)
end end
it "handles less than pairs" do it "handles less than pairs" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['less_than_pair'], inputs: inputs['less_than_pair'],
@ -200,7 +203,7 @@ describe CustomWizard::Mapper do
user: user2 user: user2
).perform).to eq(true) ).perform).to eq(true)
end end
it "handles greater than or equal pairs" do it "handles greater than or equal pairs" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['greater_than_or_equal_pair'], inputs: inputs['greater_than_or_equal_pair'],
@ -213,7 +216,7 @@ describe CustomWizard::Mapper do
user: user2 user: user2
).perform).to eq(true) ).perform).to eq(true)
end end
it "handles less than or equal pairs" do it "handles less than or equal pairs" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['less_than_or_equal_pair'], inputs: inputs['less_than_or_equal_pair'],
@ -226,7 +229,7 @@ describe CustomWizard::Mapper do
user: user2 user: user2
).perform).to eq(true) ).perform).to eq(true)
end end
it "handles regex pairs" do it "handles regex pairs" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['regex_pair'], inputs: inputs['regex_pair'],
@ -239,7 +242,7 @@ describe CustomWizard::Mapper do
user: user2 user: user2
).perform).to eq(false) ).perform).to eq(false)
end end
it "handles shorthand pairs" do it "handles shorthand pairs" do
expect(CustomWizard::Mapper.new( expect(CustomWizard::Mapper.new(
inputs: inputs['shorthand_pair'], inputs: inputs['shorthand_pair'],
@ -247,4 +250,4 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq(false) ).perform).to eq(false)
end end
end end

Datei anzeigen

@ -1,8 +1,9 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Template do describe CustomWizard::Template do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template_json) { let(:template_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
@ -13,11 +14,11 @@ describe CustomWizard::Template do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json"
).read) ).read)
} }
before do before do
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)
end end
it "saves wizard templates" do it "saves wizard templates" do
expect( expect(
PluginStoreRow.exists?( PluginStoreRow.exists?(
@ -26,51 +27,51 @@ describe CustomWizard::Template do
) )
).to eq(true) ).to eq(true)
end end
it "finds wizard templates" do it "finds wizard templates" do
expect( expect(
CustomWizard::Template.find('super_mega_fun_wizard')['id'] CustomWizard::Template.find('super_mega_fun_wizard')['id']
).to eq('super_mega_fun_wizard') ).to eq('super_mega_fun_wizard')
end end
it "removes wizard templates" do it "removes wizard templates" do
CustomWizard::Template.remove('super_mega_fun_wizard') CustomWizard::Template.remove('super_mega_fun_wizard')
expect( expect(
CustomWizard::Template.find('super_mega_fun_wizard') CustomWizard::Template.find('super_mega_fun_wizard')
).to eq(nil) ).to eq(nil)
end end
it "checks for wizard template existence" do it "checks for wizard template existence" do
expect( expect(
CustomWizard::Template.exists?('super_mega_fun_wizard') CustomWizard::Template.exists?('super_mega_fun_wizard')
).to eq(true) ).to eq(true)
end end
context "wizard template list" do context "wizard template list" do
before do before do
template_json_2 = template_json.dup template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2' template_json_2["id"] = 'super_mega_fun_wizard_2'
template_json_2["permitted"] = permitted_json['permitted'] template_json_2["permitted"] = permitted_json['permitted']
CustomWizard::Template.save(template_json_2, skip_jobs: true) CustomWizard::Template.save(template_json_2, skip_jobs: true)
template_json_3 = template_json.dup template_json_3 = template_json.dup
template_json_3["id"] = 'super_mega_fun_wizard_3' template_json_3["id"] = 'super_mega_fun_wizard_3'
template_json_3["after_signup"] = true template_json_3["after_signup"] = true
CustomWizard::Template.save(template_json_3, skip_jobs: true) CustomWizard::Template.save(template_json_3, skip_jobs: true)
end end
it "works" do it "works" do
expect( expect(
CustomWizard::Template.list.length CustomWizard::Template.list.length
).to eq(3) ).to eq(3)
end end
it "can be filtered by wizard settings" do it "can be filtered by wizard settings" do
expect( expect(
CustomWizard::Template.list(setting: "after_signup").length CustomWizard::Template.list(setting: "after_signup").length
).to eq(1) ).to eq(1)
end end
it "can be ordered" do it "can be ordered" do
expect( expect(
CustomWizard::Template.list( CustomWizard::Template.list(
@ -79,30 +80,30 @@ describe CustomWizard::Template do
).to eq('super_mega_fun_wizard_2') ).to eq('super_mega_fun_wizard_2')
end end
end end
context "after time setting" do context "after time setting" do
before do before do
freeze_time Time.now freeze_time Time.now
@scheduled_time = (Time.now + 3.hours).iso8601 @scheduled_time = (Time.now + 3.hours).iso8601
@after_time_template = template_json.dup @after_time_template = template_json.dup
@after_time_template["after_time"] = true @after_time_template["after_time"] = true
@after_time_template["after_time_scheduled"] = @scheduled_time @after_time_template["after_time_scheduled"] = @scheduled_time
end end
it 'if enabled queues jobs after wizard is saved' do it 'if enabled queues jobs after wizard is saved' do
expect_enqueued_with(job: :set_after_time_wizard, at: Time.parse(@scheduled_time).utc) do expect_enqueued_with(job: :set_after_time_wizard, at: Time.parse(@scheduled_time).utc) do
CustomWizard::Template.save(@after_time_template) CustomWizard::Template.save(@after_time_template)
end end
end end
it 'if disabled clears jobs after wizard is saved' do it 'if disabled clears jobs after wizard is saved' do
CustomWizard::Template.save(@after_time_template) CustomWizard::Template.save(@after_time_template)
@after_time_template['after_time'] = false @after_time_template['after_time'] = false
expect_not_enqueued_with(job: :set_after_time_wizard) do expect_not_enqueued_with(job: :set_after_time_wizard) do
CustomWizard::Template.save(@after_time_template) CustomWizard::Template.save(@after_time_template)
end end
end end
end end
end end

Datei anzeigen

@ -1,34 +1,35 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::TemplateValidator do describe CustomWizard::TemplateValidator do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read).with_indifferent_access ).read).with_indifferent_access
} }
it "validates valid templates" do it "validates valid templates" do
expect( expect(
CustomWizard::TemplateValidator.new(template).perform CustomWizard::TemplateValidator.new(template).perform
).to eq(true) ).to eq(true)
end end
it "invalidates templates without required attributes" do it "invalidates templates without required attributes" do
template.delete(:id) template.delete(:id)
expect( expect(
CustomWizard::TemplateValidator.new(template).perform CustomWizard::TemplateValidator.new(template).perform
).to eq(false) ).to eq(false)
end end
it "invalidates templates with duplicate ids if creating a new template" do it "invalidates templates with duplicate ids if creating a new template" do
CustomWizard::Template.save(template) CustomWizard::Template.save(template)
expect( expect(
CustomWizard::TemplateValidator.new(template, create: true).perform CustomWizard::TemplateValidator.new(template, create: true).perform
).to eq(false) ).to eq(false)
end end
it "validates after time settings" do it "validates after time settings" do
template[:after_time] = true template[:after_time] = true
template[:after_time_scheduled] = (Time.now + 3.hours).iso8601 template[:after_time_scheduled] = (Time.now + 3.hours).iso8601
@ -36,7 +37,7 @@ describe CustomWizard::TemplateValidator do
CustomWizard::TemplateValidator.new(template).perform CustomWizard::TemplateValidator.new(template).perform
).to eq(true) ).to eq(true)
end end
it "invalidates invalid after time settings" do it "invalidates invalid after time settings" do
template[:after_time] = true template[:after_time] = true
template[:after_time_scheduled] = "not a time" template[:after_time_scheduled] = "not a time"
@ -44,4 +45,4 @@ describe CustomWizard::TemplateValidator do
CustomWizard::TemplateValidator.new(template).perform CustomWizard::TemplateValidator.new(template).perform
).to eq(false) ).to eq(false)
end end
end end

Datei anzeigen

@ -1,46 +1,47 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::UpdateValidator do describe CustomWizard::UpdateValidator do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read).with_indifferent_access ).read).with_indifferent_access
} }
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
def perform_validation(step_id, submission) def perform_validation(step_id, submission)
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
updater = wizard.create_updater(step_id, submission) updater = wizard.create_updater(step_id, submission)
updater.validate updater.validate
updater updater
end end
it 'applies min length to text type fields' do it 'applies min length to text type fields' do
min_length = 3 min_length = 3
@template[:steps][0][:fields][0][:min_length] = min_length @template[:steps][0][:fields][0][:min_length] = min_length
@template[:steps][0][:fields][1][:min_length] = min_length @template[:steps][0][:fields][1][:min_length] = min_length
@template[:steps][0][:fields][2][:min_length] = min_length @template[:steps][0][:fields][2][:min_length] = min_length
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_1', step_1_field_1: 'Te') updater = perform_validation('step_1', step_1_field_1: 'Te')
expect( expect(
updater.errors.messages[:step_1_field_1].first updater.errors.messages[:step_1_field_1].first
).to eq(I18n.t('wizard.field.too_short', label: 'Text', min: min_length)) ).to eq(I18n.t('wizard.field.too_short', label: 'Text', min: min_length))
updater = perform_validation('step_1', step_1_field_2: 'Te') updater = perform_validation('step_1', step_1_field_2: 'Te')
expect( expect(
updater.errors.messages[:step_1_field_2].first updater.errors.messages[:step_1_field_2].first
).to eq(I18n.t('wizard.field.too_short', label: 'Textarea', min: min_length)) ).to eq(I18n.t('wizard.field.too_short', label: 'Textarea', min: min_length))
updater = perform_validation('step_1', step_1_field_3: 'Te') updater = perform_validation('step_1', step_1_field_3: 'Te')
expect( expect(
updater.errors.messages[:step_1_field_3].first updater.errors.messages[:step_1_field_3].first
).to eq(I18n.t('wizard.field.too_short', label: 'Composer', min: min_length)) ).to eq(I18n.t('wizard.field.too_short', label: 'Composer', min: min_length))
@ -100,35 +101,35 @@ describe CustomWizard::UpdateValidator do
updater = perform_validation('step_2', step_2_field_5: 'false') updater = perform_validation('step_2', step_2_field_5: 'false')
expect(updater.submission['step_2_field_5']).to eq(false) expect(updater.submission['step_2_field_5']).to eq(false)
end end
it 'requires required fields' do it 'requires required fields' do
@template[:steps][0][:fields][1][:required] = true @template[:steps][0][:fields][1][:required] = true
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
updater = perform_validation('step_1', step_1_field_2: nil) updater = perform_validation('step_1', step_1_field_2: nil)
expect( expect(
updater.errors.messages[:step_1_field_2].first updater.errors.messages[:step_1_field_2].first
).to eq(I18n.t('wizard.field.required', label: 'Textarea')) ).to eq(I18n.t('wizard.field.required', label: 'Textarea'))
end end
it 'validates url fields' do it 'validates url fields' do
updater = perform_validation('step_2', step_2_field_6: 'https://discourse.com') updater = perform_validation('step_2', step_2_field_6: 'https://discourse.com')
expect( expect(
updater.errors.messages[:step_2_field_6].first updater.errors.messages[:step_2_field_6].first
).to eq(nil) ).to eq(nil)
end end
it 'does not validate url fields with non-url inputs' do it 'does not validate url fields with non-url inputs' do
updater = perform_validation('step_2', step_2_field_6: 'discourse') updater = perform_validation('step_2', step_2_field_6: 'discourse')
expect( expect(
updater.errors.messages[:step_2_field_6].first updater.errors.messages[:step_2_field_6].first
).to eq(I18n.t('wizard.field.not_url', label: 'Url')) ).to eq(I18n.t('wizard.field.not_url', label: 'Url'))
end end
it 'validates empty url fields' do it 'validates empty url fields' do
updater = perform_validation('step_2', step_2_field_6: '') updater = perform_validation('step_2', step_2_field_6: '')
expect( expect(
updater.errors.messages[:step_2_field_6].first updater.errors.messages[:step_2_field_6].first
).to eq(nil) ).to eq(nil)
end end
end end

Datei anzeigen

@ -1,34 +1,35 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Wizard do describe CustomWizard::Wizard do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:trusted_user) { Fabricate(:user, trust_level: TrustLevel[3])} fab!(:trusted_user) { Fabricate(:user, trust_level: TrustLevel[3]) }
fab!(:admin_user) { Fabricate(:user, admin: true)} fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:template_json) { let(:template_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
} }
let(:permitted_json) { let(:permitted_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json"
).read) ).read)
} }
before do before do
Group.refresh_automatic_group!(:trust_level_3) Group.refresh_automatic_group!(:trust_level_3)
@permitted_template = template_json.dup @permitted_template = template_json.dup
@permitted_template["permitted"] = permitted_json["permitted"] @permitted_template["permitted"] = permitted_json["permitted"]
@wizard = CustomWizard::Wizard.new(template_json, user) @wizard = CustomWizard::Wizard.new(template_json, user)
template_json['steps'].each do |step_template| template_json['steps'].each do |step_template|
@wizard.append_step(step_template['id']) @wizard.append_step(step_template['id'])
end end
end end
def progress_step(step_id, acting_user: user, wizard: @wizard) def progress_step(step_id, acting_user: user, wizard: @wizard)
UserHistory.create( UserHistory.create(
action: UserHistory.actions[:custom_wizard_step], action: UserHistory.actions[:custom_wizard_step],
@ -36,25 +37,25 @@ describe CustomWizard::Wizard do
context: wizard.id, context: wizard.id,
subject: step_id subject: step_id
) )
end end
it "appends steps from a template" do it "appends steps from a template" do
expect(@wizard.steps.length).to eq(3) expect(@wizard.steps.length).to eq(3)
end end
it "determines the user's current step" do it "determines the user's current step" do
expect(@wizard.start.id).to eq('step_1') expect(@wizard.start.id).to eq('step_1')
progress_step('step_1') progress_step('step_1')
expect(@wizard.start.id).to eq('step_2') expect(@wizard.start.id).to eq('step_2')
end end
it "creates a step updater" do it "creates a step updater" do
expect( expect(
@wizard.create_updater('step_1', step_1_field_1: "Text input") @wizard.create_updater('step_1', step_1_field_1: "Text input")
.class .class
).to eq(CustomWizard::StepUpdater) ).to eq(CustomWizard::StepUpdater)
end end
it "determines whether a wizard is unfinished" do it "determines whether a wizard is unfinished" do
expect(@wizard.unfinished?).to eq(true) expect(@wizard.unfinished?).to eq(true)
progress_step("step_1") progress_step("step_1")
@ -64,7 +65,7 @@ describe CustomWizard::Wizard do
progress_step("step_3") progress_step("step_3")
expect(@wizard.unfinished?).to eq(false) expect(@wizard.unfinished?).to eq(false)
end end
it "determines whether a wizard has been completed by a user" do it "determines whether a wizard has been completed by a user" do
expect(@wizard.completed?).to eq(false) expect(@wizard.completed?).to eq(false)
progress_step("step_1") progress_step("step_1")
@ -72,101 +73,101 @@ describe CustomWizard::Wizard do
progress_step("step_3") progress_step("step_3")
expect(@wizard.completed?).to eq(true) expect(@wizard.completed?).to eq(true)
end end
it "is not completed if steps submitted before after time" do it "is not completed if steps submitted before after time" do
progress_step("step_1") progress_step("step_1")
progress_step("step_2") progress_step("step_2")
progress_step("step_3") progress_step("step_3")
template_json['after_time'] = true template_json['after_time'] = true
template_json['after_time_scheduled'] = Time.now + 3.hours template_json['after_time_scheduled'] = Time.now + 3.hours
wizard = CustomWizard::Wizard.new(template_json, user) wizard = CustomWizard::Wizard.new(template_json, user)
expect(wizard.completed?).to eq(false) expect(wizard.completed?).to eq(false)
end end
it "permits admins" do it "permits admins" do
expect( expect(
CustomWizard::Wizard.new(@permitted_template, admin_user).permitted? CustomWizard::Wizard.new(@permitted_template, admin_user).permitted?
).to eq(true) ).to eq(true)
end end
it "permits permitted users" do it "permits permitted users" do
expect( expect(
CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted? CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted?
).to eq(true) ).to eq(true)
end end
it "does not permit unpermitted users" do it "does not permit unpermitted users" do
expect( expect(
CustomWizard::Wizard.new(@permitted_template, user).permitted? CustomWizard::Wizard.new(@permitted_template, user).permitted?
).to eq(false) ).to eq(false)
end end
it "does not let an unpermitted user access a wizard" do it "does not let an unpermitted user access a wizard" do
expect( expect(
CustomWizard::Wizard.new(@permitted_template, user).can_access? CustomWizard::Wizard.new(@permitted_template, user).can_access?
).to eq(false) ).to eq(false)
end end
it "lets a permitted user access an incomplete wizard" do it "lets a permitted user access an incomplete wizard" do
expect( expect(
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
).to eq(true) ).to eq(true)
end end
it "lets a permitted user access a complete wizard with multiple submissions" do it "lets a permitted user access a complete wizard with multiple submissions" do
progress_step("step_1", acting_user: trusted_user) progress_step("step_1", acting_user: trusted_user)
progress_step("step_2", acting_user: trusted_user) progress_step("step_2", acting_user: trusted_user)
progress_step("step_3", acting_user: trusted_user) progress_step("step_3", acting_user: trusted_user)
expect( expect(
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
).to eq(true) ).to eq(true)
end end
it "does not let an unpermitted user access a complete wizard without multiple submissions" do it "does not let an unpermitted user access a complete wizard without multiple submissions" do
progress_step("step_1", acting_user: trusted_user) progress_step("step_1", acting_user: trusted_user)
progress_step("step_2", acting_user: trusted_user) progress_step("step_2", acting_user: trusted_user)
progress_step("step_3", acting_user: trusted_user) progress_step("step_3", acting_user: trusted_user)
@permitted_template['multiple_submissions'] = false @permitted_template['multiple_submissions'] = false
expect( expect(
CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access?
).to eq(false) ).to eq(false)
end end
it "lists the site groups" do it "lists the site groups" do
expect(@wizard.groups.length).to eq(8) expect(@wizard.groups.length).to eq(8)
end end
it "lists the site categories" do it "lists the site categories" do
expect(@wizard.categories.length).to eq(1) expect(@wizard.categories.length).to eq(1)
end end
context "submissions" do context "submissions" do
before do before do
@wizard.set_submissions(step_1_field_1: 'I am a user submission') @wizard.set_submissions(step_1_field_1: 'I am a user submission')
end end
it "sets the user's submission" do it "sets the user's submission" do
expect( expect(
PluginStore.get("#{template_json['id']}_submissions", user.id) PluginStore.get("#{template_json['id']}_submissions", user.id)
.first['step_1_field_1'] .first['step_1_field_1']
).to eq('I am a user submission') ).to eq('I am a user submission')
end end
it "lists the user's submissions" do it "lists the user's submissions" do
expect(@wizard.submissions.length).to eq(1) expect(@wizard.submissions.length).to eq(1)
end end
it "returns the user's current submission" do it "returns the user's current submission" do
expect(@wizard.current_submission['step_1_field_1']).to eq('I am a user submission') expect(@wizard.current_submission['step_1_field_1']).to eq('I am a user submission')
end end
end end
it "provides class methods to set and list submissions" do it "provides class methods to set and list submissions" do
CustomWizard::Wizard.set_submissions(template_json['id'], user, CustomWizard::Wizard.set_submissions(template_json['id'], user,
step_1_field_1: 'I am a user submission' step_1_field_1: 'I am a user submission'
@ -180,32 +181,32 @@ describe CustomWizard::Wizard do
context do context do
before do before do
CustomWizard::Template.save(@permitted_template, skip_jobs: true) CustomWizard::Template.save(@permitted_template, skip_jobs: true)
template_json_2 = template_json.dup template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2' template_json_2["id"] = 'super_mega_fun_wizard_2'
template_json_2["prompt_completion"] = true template_json_2["prompt_completion"] = true
CustomWizard::Template.save(template_json_2, skip_jobs: true) CustomWizard::Template.save(template_json_2, skip_jobs: true)
template_json_3 = template_json.dup template_json_3 = template_json.dup
template_json_3["id"] = 'super_mega_fun_wizard_3' template_json_3["id"] = 'super_mega_fun_wizard_3'
template_json_3["after_signup"] = true template_json_3["after_signup"] = true
template_json_3["prompt_completion"] = true template_json_3["prompt_completion"] = true
CustomWizard::Template.save(template_json_3, skip_jobs: true) CustomWizard::Template.save(template_json_3, skip_jobs: true)
end end
it "lists wizards the user can see" do it "lists wizards the user can see" do
expect(CustomWizard::Wizard.list(user).length).to eq(2) expect(CustomWizard::Wizard.list(user).length).to eq(2)
expect(CustomWizard::Wizard.list(trusted_user).length).to eq(3) expect(CustomWizard::Wizard.list(trusted_user).length).to eq(3)
end end
it "returns the first after signup wizard" do it "returns the first after signup wizard" do
expect(CustomWizard::Wizard.after_signup(user).id).to eq('super_mega_fun_wizard_3') expect(CustomWizard::Wizard.after_signup(user).id).to eq('super_mega_fun_wizard_3')
end end
it "lists prompt completion wizards" do it "lists prompt completion wizards" do
expect(CustomWizard::Wizard.prompt_completion(user).length).to eq(2) expect(CustomWizard::Wizard.prompt_completion(user).length).to eq(2)
end end
it "prompt completion does not include wizards user has completed" do it "prompt completion does not include wizards user has completed" do
wizard_2 = CustomWizard::Wizard.new(CustomWizard::Template.find('super_mega_fun_wizard_2'), user) wizard_2 = CustomWizard::Wizard.new(CustomWizard::Template.find('super_mega_fun_wizard_2'), user)
progress_step("step_1", wizard: wizard_2) progress_step("step_1", wizard: wizard_2)
@ -214,7 +215,7 @@ describe CustomWizard::Wizard do
expect(CustomWizard::Wizard.prompt_completion(user).length).to eq(1) expect(CustomWizard::Wizard.prompt_completion(user).length).to eq(1)
end end
end end
it "sets wizard redirects if user is permitted" do it "sets wizard redirects if user is permitted" do
CustomWizard::Template.save(@permitted_template, skip_jobs: true) CustomWizard::Template.save(@permitted_template, skip_jobs: true)
CustomWizard::Wizard.set_wizard_redirect('super_mega_fun_wizard', trusted_user) CustomWizard::Wizard.set_wizard_redirect('super_mega_fun_wizard', trusted_user)
@ -222,7 +223,7 @@ describe CustomWizard::Wizard do
trusted_user.custom_fields['redirect_to_wizard'] trusted_user.custom_fields['redirect_to_wizard']
).to eq("super_mega_fun_wizard") ).to eq("super_mega_fun_wizard")
end end
it "does not set a wizard redirect if user is not permitted" do it "does not set a wizard redirect if user is not permitted" do
CustomWizard::Template.save(@permitted_template, skip_jobs: true) CustomWizard::Template.save(@permitted_template, skip_jobs: true)
CustomWizard::Wizard.set_wizard_redirect('super_mega_fun_wizard', user) CustomWizard::Wizard.set_wizard_redirect('super_mega_fun_wizard', user)
@ -230,4 +231,4 @@ describe CustomWizard::Wizard do
trusted_user.custom_fields['redirect_to_wizard'] trusted_user.custom_fields['redirect_to_wizard']
).to eq(nil) ).to eq(nil)
end end
end end

Datei anzeigen

@ -8,110 +8,110 @@ describe "custom field extensions" do
fab!(:category) { Fabricate(:category) } fab!(:category) { Fabricate(:category) }
fab!(:group) { Fabricate(:group) } fab!(:group) { Fabricate(:group) }
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:custom_field_json) { let(:custom_field_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read) ).read)
} }
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save
end end
end end
context "topic" do context "topic" do
it "registers topic custom fields" do it "registers topic custom fields" do
topic topic
expect(Topic.get_custom_field_type("topic_field_1")).to eq(:boolean) expect(Topic.get_custom_field_type("topic_field_1")).to eq(:boolean)
end end
it "adds topic custom fields to the topic_view serializer" do it "adds topic custom fields to the topic_view serializer" do
topic.custom_fields["topic_field_1"] = true topic.custom_fields["topic_field_1"] = true
topic.save_custom_fields(true) topic.save_custom_fields(true)
serializer = TopicViewSerializer.new( serializer = TopicViewSerializer.new(
TopicView.new(topic.id, user), TopicView.new(topic.id, user),
scope: Guardian.new(user), scope: Guardian.new(user),
root: false root: false
).as_json ).as_json
expect(serializer[:topic_field_1]).to eq(true) expect(serializer[:topic_field_1]).to eq(true)
end end
it "adds topic custom fields to the topic_list_item serializer" do it "adds topic custom fields to the topic_list_item serializer" do
topic.custom_fields["topic_field_1"] = true topic.custom_fields["topic_field_1"] = true
topic.save_custom_fields(true) topic.save_custom_fields(true)
serializer = TopicListItemSerializer.new( serializer = TopicListItemSerializer.new(
topic, topic,
scope: Guardian.new(user), scope: Guardian.new(user),
root: false root: false
).as_json ).as_json
expect(serializer[:topic_field_1]).to eq(true) expect(serializer[:topic_field_1]).to eq(true)
end end
end end
context "post" do context "post" do
it "registers post custom fields" do it "registers post custom fields" do
post post
expect(Post.get_custom_field_type("post_field_1")).to eq(:integer) expect(Post.get_custom_field_type("post_field_1")).to eq(:integer)
end end
it "adds post custom fields to the post serializer" do it "adds post custom fields to the post serializer" do
post.custom_fields["post_field_1"] = 7 post.custom_fields["post_field_1"] = 7
post.save_custom_fields(true) post.save_custom_fields(true)
serializer = PostSerializer.new( serializer = PostSerializer.new(
post, post,
scope: Guardian.new(user), scope: Guardian.new(user),
root: false root: false
).as_json ).as_json
expect(serializer[:post_field_1]).to eq(7) expect(serializer[:post_field_1]).to eq(7)
end end
end end
context "category" do context "category" do
it "registers category custom fields" do it "registers category custom fields" do
category category
expect(Category.get_custom_field_type("category_field_1")).to eq(:json) expect(Category.get_custom_field_type("category_field_1")).to eq(:json)
end end
it "adds category custom fields to the basic category serializer" do it "adds category custom fields to the basic category serializer" do
category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json
category.save_custom_fields(true) category.save_custom_fields(true)
serializer = BasicCategorySerializer.new( serializer = BasicCategorySerializer.new(
category, category,
scope: Guardian.new(user), scope: Guardian.new(user),
root: false root: false
).as_json ).as_json
expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json) expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json)
end end
end end
context "group" do context "group" do
it "registers group custom fields" do it "registers group custom fields" do
group group
expect(Group.get_custom_field_type("group_field_1")).to eq(:string) expect(Group.get_custom_field_type("group_field_1")).to eq(:string)
end end
it "adds group custom fields to the basic group serializer" do it "adds group custom fields to the basic group serializer" do
group.custom_fields["group_field_1"] = "Hello" group.custom_fields["group_field_1"] = "Hello"
group.save_custom_fields(true) group.save_custom_fields(true)
serializer = BasicGroupSerializer.new( serializer = BasicGroupSerializer.new(
group, group,
scope: Guardian.new(user), scope: Guardian.new(user),
root: false root: false
).as_json ).as_json
expect(serializer[:group_field_1]).to eq("Hello") expect(serializer[:group_field_1]).to eq("Hello")
end end
end end
end end

Datei anzeigen

@ -1,59 +1,60 @@
# frozen_string_literal: true
require_relative '../plugin_helper' require_relative '../plugin_helper'
describe ExtraLocalesControllerCustomWizard, type: :request do describe ExtraLocalesControllerCustomWizard, type: :request do
let(:new_user) { Fabricate(:user, trust_level: TrustLevel[0]) } let(:new_user) { Fabricate(:user, trust_level: TrustLevel[0]) }
let(:staff_user) { Fabricate(:moderator) } let(:staff_user) { Fabricate(:moderator) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
} }
let(:permitted) { let(:permitted) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json"
).read) ).read)
} }
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
end end
before do before do
js_hash = ExtraLocalesController.bundle_js_hash("wizard") js_hash = ExtraLocalesController.bundle_js_hash("wizard")
@locale_url = "#{Discourse.base_path}/extra-locales/wizard?v=#{js_hash}" @locale_url = "#{Discourse.base_path}/extra-locales/wizard?v=#{js_hash}"
end end
it "generates the correct wizard locale url" do it "generates the correct wizard locale url" do
expect(ExtraLocalesController.url("wizard")).to eq(@locale_url) expect(ExtraLocalesController.url("wizard")).to eq(@locale_url)
end end
it "returns wizard locales when requested by user in wizard" do it "returns wizard locales when requested by user in wizard" do
sign_in(new_user) sign_in(new_user)
get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard" } get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard" }
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
it "return wizard locales if user cant access wizard" do it "return wizard locales if user cant access wizard" do
template[:permitted] = permitted["permitted"] template[:permitted] = permitted["permitted"]
CustomWizard::Template.save(template.as_json) CustomWizard::Template.save(template.as_json)
sign_in(new_user) sign_in(new_user)
get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard" } get @locale_url, headers: { 'REFERER' => "/w/super-mega-fun-wizard" }
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
it "doesnt return wizard locales to non-staff when requested outside of wizard" do it "doesnt return wizard locales to non-staff when requested outside of wizard" do
sign_in(new_user) sign_in(new_user)
get @locale_url get @locale_url
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
it "returns wizard locales to staff when requested outside of wizard" do it "returns wizard locales to staff when requested outside of wizard" do
sign_in(staff_user) sign_in(staff_user)
get @locale_url get @locale_url
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
end end

Datei anzeigen

@ -1,24 +1,24 @@
# frozen_string_literal: true
require_relative '../plugin_helper' require_relative '../plugin_helper'
describe InvitesControllerCustomWizard, type: :request do describe InvitesControllerCustomWizard, type: :request do
fab!(:topic) { Fabricate(:topic) } fab!(:topic) { Fabricate(:topic) }
let(:invite) do let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) }
Invite.invite_by_email("angus@email.com", topic.user, topic)
end
let(:template) do let(:template) do
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
end end
before do before do
@controller = InvitesController.new @controller = InvitesController.new
end end
it "redirects a user to wizard after invite if after signup is enabled" do it "redirects a user to wizard after invite if after signup is enabled" do
template['after_signup'] = true template['after_signup'] = true
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
put "/invites/show/#{invite.invite_key}.json" put "/invites/show/#{invite.invite_key}.json"
expect(response.parsed_body["redirect_to"]).to eq("/w/super-mega-fun-wizard") expect(response.parsed_body["redirect_to"]).to eq("/w/super-mega-fun-wizard")
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../plugin_helper' require_relative '../plugin_helper'
describe CustomWizardUsersController, type: :request do describe CustomWizardUsersController, type: :request do
@ -6,16 +7,16 @@ describe CustomWizardUsersController, type: :request do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
end end
before do before do
@controller = UsersController.new @controller = UsersController.new
end end
it "redirects a user to wizard after sign up if after signup is enabled" do it "redirects a user to wizard after sign up if after signup is enabled" do
template['after_signup'] = true template['after_signup'] = true
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
sign_in(Fabricate(:user)) sign_in(Fabricate(:user))
get "/u/account-created" get "/u/account-created"
expect(response).to redirect_to("/w/super-mega-fun-wizard") expect(response).to redirect_to("/w/super-mega-fun-wizard")
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../plugin_helper' require_relative '../plugin_helper'
describe CustomWizardFieldExtension do describe CustomWizardFieldExtension do
@ -6,7 +7,7 @@ describe CustomWizardFieldExtension do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/field.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/field.json"
).read).with_indifferent_access ).read).with_indifferent_access
end end
it "adds custom field attributes" do it "adds custom field attributes" do
field = Wizard::Field.new(field_hash) field = Wizard::Field.new(field_hash)
expect(field.id).to eq("field_id") expect(field.id).to eq("field_id")
@ -17,5 +18,5 @@ describe CustomWizardFieldExtension do
expect(field.key).to eq("field.locale.key") expect(field.key).to eq("field.locale.key")
expect(field.type).to eq("field_type") expect(field.type).to eq("field_type")
expect(field.content).to eq([]) expect(field.content).to eq([])
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../plugin_helper' require_relative '../plugin_helper'
describe CustomWizardStepExtension do describe CustomWizardStepExtension do
@ -6,9 +7,9 @@ describe CustomWizardStepExtension do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/step.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/step.json"
).read).with_indifferent_access ).read).with_indifferent_access
end end
it "adds custom step attributes" do it "adds custom step attributes" do
step = Wizard::Step.new(step_hash[:id]) step = Wizard::Step.new(step_hash[:id])
[ [
:title, :title,
:description, :description,
@ -19,5 +20,5 @@ describe CustomWizardStepExtension do
step.send("#{attr.to_s}=", step_hash[attr]) step.send("#{attr.to_s}=", step_hash[attr])
expect(step.send(attr)).to eq(step_hash[attr]) expect(step.send(attr)).to eq(step_hash[attr])
end end
end end
end end

Datei anzeigen

@ -6,7 +6,7 @@ describe Jobs::ClearAfterTimeWizard do
fab!(:user1) { Fabricate(:user) } fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
fab!(:user3) { Fabricate(:user) } fab!(:user3) { Fabricate(:user) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
@ -17,20 +17,20 @@ describe Jobs::ClearAfterTimeWizard do
after_time_template = template.dup after_time_template = template.dup
after_time_template["after_time"] = true after_time_template["after_time"] = true
after_time_template["after_time_scheduled"] = (Time.now + 3.hours).iso8601 after_time_template["after_time_scheduled"] = (Time.now + 3.hours).iso8601
CustomWizard::Template.save(after_time_template) CustomWizard::Template.save(after_time_template)
Jobs::SetAfterTimeWizard.new.execute(wizard_id: 'super_mega_fun_wizard') Jobs::SetAfterTimeWizard.new.execute(wizard_id: 'super_mega_fun_wizard')
expect( expect(
UserCustomField.where( UserCustomField.where(
name: 'redirect_to_wizard', name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard' value: 'super_mega_fun_wizard'
).length ).length
).to eq(3) ).to eq(3)
described_class.new.execute(wizard_id: 'super_mega_fun_wizard') described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
expect( expect(
UserCustomField.where(" UserCustomField.where("
name = 'redirect_to_wizard' AND name = 'redirect_to_wizard' AND
@ -38,4 +38,4 @@ describe Jobs::ClearAfterTimeWizard do
").exists? ").exists?
).to eq(false) ).to eq(false)
end end
end end

Datei anzeigen

@ -6,7 +6,7 @@ describe Jobs::SetAfterTimeWizard do
fab!(:user1) { Fabricate(:user) } fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
fab!(:user3) { Fabricate(:user) } fab!(:user3) { Fabricate(:user) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
@ -17,21 +17,21 @@ describe Jobs::SetAfterTimeWizard do
after_time_template = template.dup after_time_template = template.dup
after_time_template["after_time"] = true after_time_template["after_time"] = true
after_time_template["after_time_scheduled"] = (Time.now + 3.hours).iso8601 after_time_template["after_time_scheduled"] = (Time.now + 3.hours).iso8601
CustomWizard::Template.save(after_time_template) CustomWizard::Template.save(after_time_template)
messages = MessageBus.track_publish("/redirect_to_wizard") do messages = MessageBus.track_publish("/redirect_to_wizard") do
described_class.new.execute(wizard_id: 'super_mega_fun_wizard') described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
end end
expect( expect(
UserCustomField.where( UserCustomField.where(
name: 'redirect_to_wizard', name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard' value: 'super_mega_fun_wizard'
).length ).length
).to eq(3) ).to eq(3)
expect(messages.first.data).to eq("super_mega_fun_wizard") expect(messages.first.data).to eq("super_mega_fun_wizard")
expect(messages.first.user_ids).to match_array([user1.id,user2.id,user3.id]) expect(messages.first.user_ids).to match_array([user1.id, user2.id, user3.id])
end end
end end

Datei anzeigen

@ -1,14 +1,15 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper' require_relative '../../../plugin_helper'
describe CustomWizard::AdminCustomFieldsController do describe CustomWizard::AdminCustomFieldsController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:custom_field_json) { let(:custom_field_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read) ).read)
} }
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
@ -20,12 +21,12 @@ describe CustomWizard::AdminCustomFieldsController do
get "/admin/wizards/custom-fields.json" get "/admin/wizards/custom-fields.json"
expect(response.parsed_body.length).to eq(4) expect(response.parsed_body.length).to eq(4)
end end
it "saves custom fields" do it "saves custom fields" do
topic_field = CustomWizard::CustomField.find_by_name('topic_field_1') topic_field = CustomWizard::CustomField.find_by_name('topic_field_1')
topic_field_json = topic_field.as_json topic_field_json = topic_field.as_json
topic_field_json['type'] = 'string' topic_field_json['type'] = 'string'
put "/admin/wizards/custom-fields.json", params: { put "/admin/wizards/custom-fields.json", params: {
custom_field: topic_field_json custom_field: topic_field_json
} }
@ -34,7 +35,7 @@ describe CustomWizard::AdminCustomFieldsController do
CustomWizard::CustomField.find_by_name('topic_field_1').type CustomWizard::CustomField.find_by_name('topic_field_1').type
).to eq('string') ).to eq('string')
end end
it "destroys custom fields" do it "destroys custom fields" do
topic_field = custom_field_json['custom_fields'][0] topic_field = custom_field_json['custom_fields'][0]
delete "/admin/wizards/custom-fields/#{topic_field["name"]}.json" delete "/admin/wizards/custom-fields/#{topic_field["name"]}.json"
@ -43,4 +44,4 @@ describe CustomWizard::AdminCustomFieldsController do
CustomWizard::CustomField.exists?('topic_field_1') CustomWizard::CustomField.exists?('topic_field_1')
).to eq(false) ).to eq(false)
end end
end end

Datei anzeigen

@ -1,8 +1,9 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper' require_relative '../../../plugin_helper'
describe CustomWizard::AdminLogsController do describe CustomWizard::AdminLogsController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
before do before do
CustomWizard::Log.create("First log message") CustomWizard::Log.create("First log message")
CustomWizard::Log.create("Second log message") CustomWizard::Log.create("Second log message")
@ -14,9 +15,9 @@ describe CustomWizard::AdminLogsController do
get "/admin/wizards/logs.json" get "/admin/wizards/logs.json"
expect(response.parsed_body.length).to eq(3) expect(response.parsed_body.length).to eq(3)
end end
it "paginates" do it "paginates" do
get "/admin/wizards/logs.json", params: { page: 1, limit: 2 } get "/admin/wizards/logs.json", params: { page: 1, limit: 2 }
expect(response.parsed_body.length).to eq(1) expect(response.parsed_body.length).to eq(1)
end end
end end

Datei anzeigen

@ -1,17 +1,18 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper' require_relative '../../../plugin_helper'
describe CustomWizard::AdminManagerController do describe CustomWizard::AdminManagerController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
} }
before do before do
sign_in(admin_user) sign_in(admin_user)
template_2 = template.dup template_2 = template.dup
template_2["id"] = 'super_mega_fun_wizard_2' template_2["id"] = 'super_mega_fun_wizard_2'
@ -20,17 +21,17 @@ describe CustomWizard::AdminManagerController do
template_3["after_signup"] = true template_3["after_signup"] = true
@template_array = [template, template_2, template_3] @template_array = [template, template_2, template_3]
FileUtils.mkdir_p(file_from_fixtures_tmp_folder) unless Dir.exists?(file_from_fixtures_tmp_folder) FileUtils.mkdir_p(file_from_fixtures_tmp_folder) unless Dir.exists?(file_from_fixtures_tmp_folder)
@tmp_file_path = File.join(file_from_fixtures_tmp_folder, SecureRandom.hex << 'wizards.json') @tmp_file_path = File.join(file_from_fixtures_tmp_folder, SecureRandom.hex << 'wizards.json')
File.write(@tmp_file_path, @template_array.to_json) File.write(@tmp_file_path, @template_array.to_json)
end end
it 'exports all the wizard templates' do it 'exports all the wizard templates' do
@template_array.each do |template| @template_array.each do |template|
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
end end
get '/admin/wizards/manager/export.json', params: { get '/admin/wizards/manager/export.json', params: {
wizard_ids: [ wizard_ids: [
'super_mega_fun_wizard', 'super_mega_fun_wizard',
@ -38,38 +39,38 @@ describe CustomWizard::AdminManagerController do
'super_mega_fun_wizard_3' 'super_mega_fun_wizard_3'
] ]
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body).to match_array(@template_array) expect(response.parsed_body).to match_array(@template_array)
end end
context "import" do context "import" do
it "works" do it "works" do
templates = @template_array.map { |t| t.slice('id', 'name') } templates = @template_array.map { |t| t.slice('id', 'name') }
post '/admin/wizards/manager/import.json', params: { post '/admin/wizards/manager/import.json', params: {
file: fixture_file_upload(File.open(@tmp_file_path)) file: fixture_file_upload(File.open(@tmp_file_path))
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['imported']).to match_array(templates) expect(response.parsed_body['imported']).to match_array(templates)
expect(CustomWizard::Template.list.map {|t| t.slice('id', 'name') }).to match_array(templates) expect(CustomWizard::Template.list.map { |t| t.slice('id', 'name') }).to match_array(templates)
end end
it 'rejects a template with the same id as a saved template' do it 'rejects a template with the same id as a saved template' do
templates = @template_array.map { |t| t.slice('id', 'name') } templates = @template_array.map { |t| t.slice('id', 'name') }
post '/admin/wizards/manager/import.json', params: { post '/admin/wizards/manager/import.json', params: {
file: fixture_file_upload(File.open(@tmp_file_path)) file: fixture_file_upload(File.open(@tmp_file_path))
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['imported']).to match_array(templates) expect(response.parsed_body['imported']).to match_array(templates)
post '/admin/wizards/manager/import.json', params: { post '/admin/wizards/manager/import.json', params: {
file: fixture_file_upload(File.open(@tmp_file_path)) file: fixture_file_upload(File.open(@tmp_file_path))
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['failures']).to match_array( expect(response.parsed_body['failures']).to match_array(
@template_array.map do |t| @template_array.map do |t|
@ -81,14 +82,14 @@ describe CustomWizard::AdminManagerController do
) )
end end
end end
it 'destroys wizard templates' do it 'destroys wizard templates' do
templates = @template_array.map { |t| t.slice('id', 'name') } templates = @template_array.map { |t| t.slice('id', 'name') }
@template_array.each do |template| @template_array.each do |template|
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
end end
delete '/admin/wizards/manager/destroy.json', params: { delete '/admin/wizards/manager/destroy.json', params: {
wizard_ids: [ wizard_ids: [
'super_mega_fun_wizard', 'super_mega_fun_wizard',
@ -96,9 +97,9 @@ describe CustomWizard::AdminManagerController do
'super_mega_fun_wizard_3' 'super_mega_fun_wizard_3'
] ]
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['destroyed']).to match_array(templates) expect(response.parsed_body['destroyed']).to match_array(templates)
expect(CustomWizard::Template.list.length).to eq(0) expect(CustomWizard::Template.list.length).to eq(0)
end end
end end

Datei anzeigen

@ -1,16 +1,17 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper' require_relative '../../../plugin_helper'
describe CustomWizard::AdminSubmissionsController do describe CustomWizard::AdminSubmissionsController do
fab!(:admin_user) {Fabricate(:user, admin: true)} fab!(:admin_user) { Fabricate(:user, admin: true) }
fab!(:user1) {Fabricate(:user)} fab!(:user1) { Fabricate(:user) }
fab!(:user2) {Fabricate(:user)} fab!(:user2) { Fabricate(:user) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
} }
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
CustomWizard::Wizard.set_submissions(template['id'], user1, CustomWizard::Wizard.set_submissions(template['id'], user1,
@ -27,19 +28,19 @@ describe CustomWizard::AdminSubmissionsController do
expect(response.parsed_body.length).to eq(1) expect(response.parsed_body.length).to eq(1)
expect(response.parsed_body.first['id']).to eq(template['id']) expect(response.parsed_body.first['id']).to eq(template['id'])
end end
it "returns the all user's submissions for a wizard" do it "returns the all user's submissions for a wizard" do
get "/admin/wizards/submissions/#{template['id']}.json" get "/admin/wizards/submissions/#{template['id']}.json"
expect(response.parsed_body['submissions'].length).to eq(2) expect(response.parsed_body['submissions'].length).to eq(2)
end end
it "returns the all user's submissions for a wizard" do it "returns the all user's submissions for a wizard" do
get "/admin/wizards/submissions/#{template['id']}.json" get "/admin/wizards/submissions/#{template['id']}.json"
expect(response.parsed_body['submissions'].length).to eq(2) expect(response.parsed_body['submissions'].length).to eq(2)
end end
it "downloads all user submissions" do it "downloads all user submissions" do
get "/admin/wizards/submissions/#{template['id']}/download" get "/admin/wizards/submissions/#{template['id']}/download"
expect(response.parsed_body.length).to eq(2) expect(response.parsed_body.length).to eq(2)
end end
end end

Datei anzeigen

@ -1,29 +1,30 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper' require_relative '../../../plugin_helper'
describe CustomWizard::AdminWizardController do describe CustomWizard::AdminWizardController do
fab!(:admin_user) {Fabricate(:user, admin: true)} fab!(:admin_user) { Fabricate(:user, admin: true) }
fab!(:user1) {Fabricate(:user)} fab!(:user1) { Fabricate(:user) }
fab!(:user2) {Fabricate(:user)} fab!(:user2) { Fabricate(:user) }
let(:template) { let(:template) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read) ).read)
} }
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
template_2 = template.dup template_2 = template.dup
template_2["id"] = 'super_mega_fun_wizard_2' template_2["id"] = 'super_mega_fun_wizard_2'
template_2["permitted"] = template_2['permitted'] template_2["permitted"] = template_2['permitted']
CustomWizard::Template.save(template_2, skip_jobs: true) CustomWizard::Template.save(template_2, skip_jobs: true)
template_3 = template.dup template_3 = template.dup
template_3["id"] = 'super_mega_fun_wizard_3' template_3["id"] = 'super_mega_fun_wizard_3'
template_3["after_signup"] = true template_3["after_signup"] = true
CustomWizard::Template.save(template_3, skip_jobs: true) CustomWizard::Template.save(template_3, skip_jobs: true)
sign_in(admin_user) sign_in(admin_user)
end end
@ -36,31 +37,31 @@ describe CustomWizard::AdminWizardController do
response.parsed_body['field_types'].keys response.parsed_body['field_types'].keys
).to eq(CustomWizard::Field.types.keys.map(&:to_s)) ).to eq(CustomWizard::Field.types.keys.map(&:to_s))
end end
it "returns a wizard template" do it "returns a wizard template" do
get "/admin/wizards/wizard/#{template['id']}.json" get "/admin/wizards/wizard/#{template['id']}.json"
expect(response.parsed_body['id']).to eq(template['id']) expect(response.parsed_body['id']).to eq(template['id'])
expect(response.parsed_body['steps'].length).to eq(3) expect(response.parsed_body['steps'].length).to eq(3)
end end
it "removes wizard templates" do it "removes wizard templates" do
delete "/admin/wizards/wizard/#{template['id']}.json" delete "/admin/wizards/wizard/#{template['id']}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(CustomWizard::Template.exists?(template['id'])).to eq(false) expect(CustomWizard::Template.exists?(template['id'])).to eq(false)
end end
it "saves wizard templates" do it "saves wizard templates" do
template_updated = template.dup template_updated = template.dup
template_updated['name'] = "Super Mega Fun Wizard 2" template_updated['name'] = "Super Mega Fun Wizard 2"
template_updated['multiple_submissions'] = false template_updated['multiple_submissions'] = false
template_updated['steps'][0]['fields'][0]['label'] = "Text 2" template_updated['steps'][0]['fields'][0]['label'] = "Text 2"
put "/admin/wizards/wizard/#{template['id']}.json", params: { wizard: template_updated } put "/admin/wizards/wizard/#{template['id']}.json", params: { wizard: template_updated }
expect(response.status).to eq(200) expect(response.status).to eq(200)
updated_template = CustomWizard::Template.find('super_mega_fun_wizard') updated_template = CustomWizard::Template.find('super_mega_fun_wizard')
expect(updated_template['name']).to eq("Super Mega Fun Wizard 2") expect(updated_template['name']).to eq("Super Mega Fun Wizard 2")
expect(updated_template['multiple_submissions']).to eq("false") expect(updated_template['multiple_submissions']).to eq("false")
expect(updated_template['steps'][0]['fields'][0]['label']).to eq("Text 2") expect(updated_template['steps'][0]['fields'][0]['label']).to eq("Text 2")
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe ApplicationController do describe ApplicationController do
@ -7,7 +8,7 @@ describe ApplicationController do
username: 'angus', username: 'angus',
email: "angus@email.com", email: "angus@email.com",
trust_level: TrustLevel[3] trust_level: TrustLevel[3]
) )
} }
before do before do
@ -18,23 +19,23 @@ describe ApplicationController do
skip_jobs: true) skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
context "with signed in user" do context "with signed in user" do
before do before do
sign_in(user) sign_in(user)
end end
context "who is required to complete wizard" do context "who is required to complete wizard" do
before do before do
user.custom_fields['redirect_to_wizard'] = 'super_mega_fun_wizard' user.custom_fields['redirect_to_wizard'] = 'super_mega_fun_wizard'
user.save_custom_fields(true) user.save_custom_fields(true)
end end
it "redirects if user is required to complete a wizard" do it "redirects if user is required to complete a wizard" do
get "/" get "/"
expect(response).to redirect_to("/w/super-mega-fun-wizard") expect(response).to redirect_to("/w/super-mega-fun-wizard")
end end
it "saves original destination of user" do it "saves original destination of user" do
get '/', headers: { 'REFERER' => "/t/2" } get '/', headers: { 'REFERER' => "/t/2" }
expect( expect(
@ -43,7 +44,7 @@ describe ApplicationController do
).to eq("/t/2") ).to eq("/t/2")
end end
end end
context "who is not required to complete wizard" do context "who is not required to complete wizard" do
it "does nothing" do it "does nothing" do
get "/" get "/"
@ -51,11 +52,11 @@ describe ApplicationController do
end end
end end
end end
context "with guest" do context "with guest" do
it "does nothing" do it "does nothing" do
get "/" get "/"
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
end end
end end

Datei anzeigen

@ -8,88 +8,87 @@ describe "custom field extensions" do
let!(:category) { Fabricate(:category) } let!(:category) { Fabricate(:category) }
let!(:user) { Fabricate(:user) } let!(:user) { Fabricate(:user) }
let!(:group) { Fabricate(:group, users: [user]) } let!(:group) { Fabricate(:group, users: [user]) }
let(:custom_field_json) { let(:custom_field_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read) ).read)
} }
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save
end end
end end
it "adds topic custom fields to the show topic response" do it "adds topic custom fields to the show topic response" do
topic.custom_fields["topic_field_1"] = true topic.custom_fields["topic_field_1"] = true
topic.save_custom_fields(true) topic.save_custom_fields(true)
get "/t/#{topic.slug}/#{topic.id}.json" get "/t/#{topic.slug}/#{topic.id}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body["topic_field_1"]).to eq(true) expect(response.parsed_body["topic_field_1"]).to eq(true)
end end
it "adds category custom fields to the show categories response" do it "adds category custom fields to the show categories response" do
category.custom_fields["category_field_1"] = { a: 1, b: 2 } category.custom_fields["category_field_1"] = { a: 1, b: 2 }
category.save_custom_fields(true) category.save_custom_fields(true)
get "/c/#{category.id}/show.json" get "/c/#{category.id}/show.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body["category"]["category_field_1"]).to eq({ a: 1, b: 2 }.as_json) expect(response.parsed_body["category"]["category_field_1"]).to eq({ a: 1, b: 2 }.as_json)
end end
it "adds group custom fields to the show group response" do it "adds group custom fields to the show group response" do
group.custom_fields["group_field_1"] = "Group cf entry" group.custom_fields["group_field_1"] = "Group cf entry"
group.save_custom_fields(true) group.save_custom_fields(true)
sign_in(user) sign_in(user)
get "/groups/#{group.name}.json" get "/groups/#{group.name}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['group']['group_field_1']).to eq("Group cf entry") expect(response.parsed_body['group']['group_field_1']).to eq("Group cf entry")
end end
it "adds post custom fields to the show post response" do it "adds post custom fields to the show post response" do
post.custom_fields["post_field_1"] = 7 post.custom_fields["post_field_1"] = 7
post.save_custom_fields(true) post.save_custom_fields(true)
get "/posts/#{post.id}.json" get "/posts/#{post.id}.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['post_field_1']).to eq(7) expect(response.parsed_body['post_field_1']).to eq(7)
end end
context "preloaded" do context "preloaded" do
it "preloads category custom fields on site categories" do it "preloads category custom fields on site categories" do
Site.preloaded_category_custom_fields << "other_field" Site.preloaded_category_custom_fields << "other_field"
category.custom_fields["category_field_1"] = { a: 1, b: 2 } category.custom_fields["category_field_1"] = { a: 1, b: 2 }
category.save_custom_fields(true) category.save_custom_fields(true)
get "/site.json" get "/site.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
site_category = response.parsed_body['categories'].select { |c| c['id'] == category.id }.first site_category = response.parsed_body['categories'].select { |c| c['id'] == category.id }.first
expect(site_category["category_field_1"]).to eq({ a: 1, b: 2 }.as_json) expect(site_category["category_field_1"]).to eq({ a: 1, b: 2 }.as_json)
end end
it "preloads group custom fields on group index" do it "preloads group custom fields on group index" do
Group.preloaded_custom_field_names << "other_field" Group.preloaded_custom_field_names << "other_field"
group = Fabricate(:group) group = Fabricate(:group)
group.custom_fields["group_field_1"] = "Group cf entry" group.custom_fields["group_field_1"] = "Group cf entry"
group.save_custom_fields(true) group.save_custom_fields(true)
get "/groups.json" get "/groups.json"
expect(response.status).to eq(200) expect(response.status).to eq(200)
group = response.parsed_body['groups'].select { |g| g['id'] == group.id }.first group = response.parsed_body['groups'].select { |g| g['id'] == group.id }.first
expect(group['group_field_1']).to eq("Group cf entry") expect(group['group_field_1']).to eq("Group cf entry")
end end
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::StepsController do describe CustomWizard::StepsController do
@ -7,7 +8,7 @@ describe CustomWizard::StepsController do
username: 'angus', username: 'angus',
email: "angus@email.com", email: "angus@email.com",
trust_level: TrustLevel[3] trust_level: TrustLevel[3]
) )
} }
before do before do
@ -18,7 +19,7 @@ describe CustomWizard::StepsController do
skip_jobs: true) skip_jobs: true)
sign_in(user) sign_in(user)
end end
it 'performs a step update' do it 'performs a step update' do
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: { fields: {
@ -26,17 +27,17 @@ describe CustomWizard::StepsController do
} }
} }
expect(response.status).to eq(200) expect(response.status).to eq(200)
wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build
expect(wizard.current_submission['step_1_field_1']).to eq("Text input") expect(wizard.current_submission['step_1_field_1']).to eq("Text input")
expect(wizard.start.id).to eq("step_2") expect(wizard.start.id).to eq("step_2")
end end
it "works if the step has no fields" do it "works if the step has no fields" do
put '/w/super-mega-fun-wizard/steps/step_1.json' put '/w/super-mega-fun-wizard/steps/step_1.json'
expect(response.status).to eq(200) expect(response.status).to eq(200)
wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build
expect(wizard.start.id).to eq("step_2") expect(wizard.start.id).to eq("step_2")
end end
end end

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::WizardController do describe CustomWizard::WizardController do
@ -7,7 +8,7 @@ describe CustomWizard::WizardController do
username: 'angus', username: 'angus',
email: "angus@email.com", email: "angus@email.com",
trust_level: TrustLevel[3] trust_level: TrustLevel[3]
) )
} }
before do before do
@ -19,40 +20,40 @@ describe CustomWizard::WizardController do
@template = CustomWizard::Template.find("super_mega_fun_wizard") @template = CustomWizard::Template.find("super_mega_fun_wizard")
sign_in(user) sign_in(user)
end end
context 'plugin disabled' do context 'plugin disabled' do
before do before do
SiteSetting.custom_wizard_enabled = false SiteSetting.custom_wizard_enabled = false
end end
it 'redirects to root' do it 'redirects to root' do
get '/w/super-mega-fun-wizard', xhr: true get '/w/super-mega-fun-wizard', xhr: true
expect(response).to redirect_to("/") expect(response).to redirect_to("/")
end end
end end
it 'returns wizard' do it 'returns wizard' do
get '/w/super-mega-fun-wizard.json' get '/w/super-mega-fun-wizard.json'
expect(response.parsed_body["id"]).to eq("super_mega_fun_wizard") expect(response.parsed_body["id"]).to eq("super_mega_fun_wizard")
end end
it 'returns missing message if no wizard exists' do it 'returns missing message if no wizard exists' do
get '/w/super-mega-fun-wizards.json' get '/w/super-mega-fun-wizards.json'
expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.") expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.")
end end
it 'skips a wizard if user is allowed to skip' do it 'skips a wizard if user is allowed to skip' do
put '/w/super-mega-fun-wizard/skip.json' put '/w/super-mega-fun-wizard/skip.json'
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
it '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
@template['required'] = 'true' @template['required'] = 'true'
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
put '/w/super-mega-fun-wizard/skip.json' put '/w/super-mega-fun-wizard/skip.json'
expect(response.parsed_body['error']).to eq("Wizard can't be skipped") expect(response.parsed_body['error']).to eq("Wizard can't be skipped")
end end
it 'skip response contains a redirect_to if in users submissions' do it 'skip response contains a redirect_to if in users submissions' do
CustomWizard::Wizard.set_submissions(@template['id'], user, CustomWizard::Wizard.set_submissions(@template['id'], user,
redirect_to: '/t/2' redirect_to: '/t/2'
@ -60,4 +61,4 @@ describe CustomWizard::WizardController do
put '/w/super-mega-fun-wizard/skip.json' put '/w/super-mega-fun-wizard/skip.json'
expect(response.parsed_body['redirect_to']).to eq('/t/2') expect(response.parsed_body['redirect_to']).to eq('/t/2')
end end
end end

Datei anzeigen

@ -4,7 +4,7 @@ require_relative '../../plugin_helper'
describe CustomWizard::BasicWizardSerializer do describe CustomWizard::BasicWizardSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
it 'should return basic wizard attributes' do it 'should return basic wizard attributes' do
CustomWizard::Template.save( CustomWizard::Template.save(
JSON.parse(File.open( JSON.parse(File.open(
@ -18,4 +18,4 @@ describe CustomWizard::BasicWizardSerializer do
expect(json[:basic_wizard][:id]).to eq("super_mega_fun_wizard") expect(json[:basic_wizard][:id]).to eq("super_mega_fun_wizard")
expect(json[:basic_wizard][:name]).to eq("Super Mega Fun Wizard") expect(json[:basic_wizard][:name]).to eq("Super Mega Fun Wizard")
end end
end end

Datei anzeigen

@ -4,18 +4,18 @@ require_relative '../../plugin_helper'
describe CustomWizard::CustomFieldSerializer do describe CustomWizard::CustomFieldSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:custom_field_json) { let(:custom_field_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read) ).read)
} }
it 'should return custom field attributes' do it 'should return custom field attributes' do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
CustomWizard::CustomField.new(nil, field_json).save CustomWizard::CustomField.new(nil, field_json).save
end end
json = CustomWizard::CustomFieldSerializer.new( json = CustomWizard::CustomFieldSerializer.new(
CustomWizard::CustomField.find_by_name("topic_field_1"), CustomWizard::CustomField.find_by_name("topic_field_1"),
scope: Guardian.new(user), scope: Guardian.new(user),
@ -24,6 +24,6 @@ describe CustomWizard::CustomFieldSerializer do
expect(json[:name]).to eq("topic_field_1") expect(json[:name]).to eq("topic_field_1")
expect(json[:klass]).to eq("topic") expect(json[:klass]).to eq("topic")
expect(json[:type]).to eq("boolean") expect(json[:type]).to eq("boolean")
expect(json[:serializers]).to match_array(["topic_list_item","topic_view"]) expect(json[:serializers]).to match_array(["topic_list_item", "topic_view"])
end end
end end

Datei anzeigen

@ -4,16 +4,16 @@ require_relative '../../plugin_helper'
describe CustomWizard::LogSerializer do describe CustomWizard::LogSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
it 'should return log attributes' do it 'should return log attributes' do
CustomWizard::Log.create("First log message") CustomWizard::Log.create("First log message")
CustomWizard::Log.create("Second log message") CustomWizard::Log.create("Second log message")
json_array = ActiveModel::ArraySerializer.new( json_array = ActiveModel::ArraySerializer.new(
CustomWizard::Log.list(0), CustomWizard::Log.list(0),
each_serializer: CustomWizard::LogSerializer each_serializer: CustomWizard::LogSerializer
).as_json ).as_json
expect(json_array.length).to eq(2) expect(json_array.length).to eq(2)
expect(json_array[0][:message]).to eq("Second log message") expect(json_array[0][:message]).to eq("Second log message")
end end
end end

Datei anzeigen

@ -13,7 +13,7 @@ describe CustomWizard::FieldSerializer do
skip_jobs: true) skip_jobs: true)
@wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build @wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build
end end
it "should return basic field attributes" do it "should return basic field attributes" do
json_array = ActiveModel::ArraySerializer.new( json_array = ActiveModel::ArraySerializer.new(
@wizard.steps.first.fields, @wizard.steps.first.fields,
@ -24,7 +24,7 @@ describe CustomWizard::FieldSerializer do
expect(json_array[0][:label]).to eq("<p>Text</p>") expect(json_array[0][:label]).to eq("<p>Text</p>")
expect(json_array[0][:description]).to eq("Text field description.") expect(json_array[0][:description]).to eq("Text field description.")
end end
it "should return optional field attributes" do it "should return optional field attributes" do
json_array = ActiveModel::ArraySerializer.new( json_array = ActiveModel::ArraySerializer.new(
@wizard.steps.second.fields, @wizard.steps.second.fields,
@ -32,7 +32,7 @@ describe CustomWizard::FieldSerializer do
scope: Guardian.new(user) scope: Guardian.new(user)
).as_json ).as_json
expect(json_array[0][:format]).to eq("YYYY-MM-DD") expect(json_array[0][:format]).to eq("YYYY-MM-DD")
expect(json_array[5][:file_types]).to eq(".jpg,.png") expect(json_array[3][:number]).to eq(4)
expect(json_array[4][:number]).to eq(5) expect(json_array[6][:file_types]).to eq(".jpg,.png")
end end
end end

Datei anzeigen

@ -5,7 +5,7 @@ require_relative '../../plugin_helper'
describe CustomWizard::WizardSerializer do describe CustomWizard::WizardSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:category) { Fabricate(:category) } fab!(:category) { Fabricate(:category) }
let(:similar_topics_validation) { let(:similar_topics_validation) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/validation/similar_topics.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/validation/similar_topics.json"
@ -20,7 +20,7 @@ describe CustomWizard::WizardSerializer do
skip_jobs: true) skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
it 'should return the wizard attributes' do it 'should return the wizard attributes' do
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
@ -31,7 +31,7 @@ describe CustomWizard::WizardSerializer do
expect(json[:wizard][:background]).to eq("#333333") expect(json[:wizard][:background]).to eq("#333333")
expect(json[:wizard][:required]).to eq(false) expect(json[:wizard][:required]).to eq(false)
end end
it 'should return the wizard steps' do it 'should return the wizard steps' do
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
@ -39,7 +39,7 @@ describe CustomWizard::WizardSerializer do
).as_json ).as_json
expect(json[:wizard][:steps].length).to eq(3) expect(json[:wizard][:steps].length).to eq(3)
end end
it "should return the wizard user attributes" do it "should return the wizard user attributes" do
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
@ -49,19 +49,19 @@ describe CustomWizard::WizardSerializer do
json[:wizard][:user] json[:wizard][:user]
).to eq(BasicUserSerializer.new(user, root: false).as_json) ).to eq(BasicUserSerializer.new(user, root: false).as_json)
end end
it "should not return categories if there are no category fields" do it "should not return categories if there are no category fields" do
@template[:steps][2][:fields].delete_at(2) @template[:steps][2][:fields].delete_at(2)
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user) scope: Guardian.new(user)
).as_json ).as_json
expect(json[:wizard][:categories].present?).to eq(false) expect(json[:wizard][:categories].present?).to eq(false)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(false) expect(json[:wizard][:uncategorized_category_id].present?).to eq(false)
end end
it "should return categories if there is a category selector field" do it "should return categories if there is a category selector field" do
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
@ -70,11 +70,11 @@ describe CustomWizard::WizardSerializer do
expect(json[:wizard][:categories].present?).to eq(true) expect(json[:wizard][:categories].present?).to eq(true)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true) expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
end end
it "should return categories if there is a similar topics validation scoped to category(s)" do it "should return categories if there is a similar topics validation scoped to category(s)" do
@template[:steps][0][:fields][0][:validations] = similar_topics_validation[:validations] @template[:steps][0][:fields][0][:validations] = similar_topics_validation[:validations]
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user) scope: Guardian.new(user)
@ -82,7 +82,7 @@ describe CustomWizard::WizardSerializer do
expect(json[:wizard][:categories].present?).to eq(true) expect(json[:wizard][:categories].present?).to eq(true)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true) expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
end end
it 'should return groups if there is a group selector field' do it 'should return groups if there is a group selector field' do
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
@ -90,15 +90,15 @@ describe CustomWizard::WizardSerializer do
).as_json ).as_json
expect(json[:wizard][:groups].length).to eq(8) expect(json[:wizard][:groups].length).to eq(8)
end end
it 'should not return groups if there is not a group selector field' do it 'should not return groups if there is not a group selector field' do
@template[:steps][2][:fields].delete_at(3) @template[:steps][2][:fields].delete_at(3)
CustomWizard::Template.save(@template) CustomWizard::Template.save(@template)
json = CustomWizard::WizardSerializer.new( json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build, CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user) scope: Guardian.new(user)
).as_json ).as_json
expect(json[:wizard][:groups].present?).to eq(false) expect(json[:wizard][:groups].present?).to eq(false)
end end
end end

Datei anzeigen

@ -4,13 +4,13 @@ require_relative '../../plugin_helper'
describe CustomWizard::StepSerializer do describe CustomWizard::StepSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:required_data_json) { let(:required_data_json) {
JSON.parse(File.open( JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/required_data.json" "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/required_data.json"
).read) ).read)
} }
before do before do
CustomWizard::Template.save( CustomWizard::Template.save(
JSON.parse(File.open( JSON.parse(File.open(
@ -19,7 +19,7 @@ describe CustomWizard::StepSerializer do
skip_jobs: true) skip_jobs: true)
@wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build @wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build
end end
it 'should return basic step attributes' do it 'should return basic step attributes' do
json_array = ActiveModel::ArraySerializer.new( json_array = ActiveModel::ArraySerializer.new(
@wizard.steps, @wizard.steps,
@ -29,7 +29,7 @@ describe CustomWizard::StepSerializer do
expect(json_array[0][:wizard_step][:title]).to eq("Text") expect(json_array[0][:wizard_step][:title]).to eq("Text")
expect(json_array[0][:wizard_step][:description]).to eq("Text inputs!") expect(json_array[0][:wizard_step][:description]).to eq("Text inputs!")
end end
it 'should return fields' do it 'should return fields' do
json_array = ActiveModel::ArraySerializer.new( json_array = ActiveModel::ArraySerializer.new(
@wizard.steps, @wizard.steps,
@ -38,14 +38,14 @@ describe CustomWizard::StepSerializer do
).as_json ).as_json
expect(json_array[0][:wizard_step][:fields].length).to eq(4) expect(json_array[0][:wizard_step][:fields].length).to eq(4)
end end
context 'with required data' do context 'with required data' do
before do before do
@template[:steps][0][:required_data] = required_data_json['required_data'] @template[:steps][0][:required_data] = required_data_json['required_data']
@template[:steps][0][:required_data_message] = required_data_json['required_data_message'] @template[:steps][0][:required_data_message] = required_data_json['required_data_message']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
it 'should return permitted attributes' do it 'should return permitted attributes' do
json_array = ActiveModel::ArraySerializer.new( json_array = ActiveModel::ArraySerializer.new(
@wizard.steps, @wizard.steps,
@ -56,4 +56,4 @@ describe CustomWizard::StepSerializer do
expect(json_array[0][:wizard_step][:permitted_message]).to eq("Missing required data") expect(json_array[0][:wizard_step][:permitted_message]).to eq("Missing required data")
end end
end end
end end