0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-05-19 23:40:07 +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
get ':wizard_id' => 'wizard#index'
put ':wizard_id/skip' => 'wizard#skip'
@ -13,21 +14,21 @@ Discourse::Application.routes.append do
scope module: 'custom_wizard', constraints: AdminConstraint.new do
get 'admin/wizards' => 'admin#index'
get 'admin/wizards/wizard' => 'admin_wizard#index'
get 'admin/wizards/wizard/create' => 'admin#index'
get 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#show'
put 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#save'
delete 'admin/wizards/wizard/:wizard_id' => 'admin_wizard#remove'
get 'admin/wizards/custom-fields' => 'admin_custom_fields#index'
put 'admin/wizards/custom-fields' => 'admin_custom_fields#update'
delete 'admin/wizards/custom-fields/:name' => 'admin_custom_fields#destroy'
get 'admin/wizards/submissions' => 'admin_submissions#index'
get 'admin/wizards/submissions/:wizard_id' => 'admin_submissions#show'
get 'admin/wizards/submissions/:wizard_id/download' => 'admin_submissions#download'
get 'admin/wizards/api' => 'admin_api#list'
get 'admin/wizards/api/:name' => 'admin_api#find'
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'
get 'admin/wizards/api/:name/redirect' => 'admin_api#redirect'
get 'admin/wizards/api/:name/authorize' => 'admin_api#authorize'
get 'admin/wizards/logs' => 'admin_logs#index'
get 'admin/wizards/manager' => 'admin_manager#index'
get 'admin/wizards/manager/export' => 'admin_manager#export'
post 'admin/wizards/manager/import' => 'admin_manager#import'
delete 'admin/wizards/manager/destroy' => 'admin_manager#destroy'
end
end
end

Datei anzeigen

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

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::AdminApiController < CustomWizard::AdminController
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.get_token(params[:name])
return redirect_to path('/admin/wizards/apis/' + params[:name])
redirect_to path('/admin/wizards/apis/' + params[:name])
end
private

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

@ -1,3 +1,4 @@
# frozen_string_literal: true
class CustomWizard::Field
def self.types
@types ||= {
@ -64,7 +65,7 @@ class CustomWizard::Field
@require_assets ||= {}
end
def self.register(type, plugin = nil, asset_paths = [], opts={})
def self.register(type, plugin = nil, asset_paths = [], opts = {})
if type
types[type.to_sym] ||= {}
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
include ActiveModel::Serialization
attr_accessor :message, :date
PAGE_LIMIT = 100
def initialize(attrs)
@message = attrs['message']
@date = attrs['date']
end
def self.create(message)
log_id = SecureRandom.hex(12)
PluginStore.set('custom_wizard_log',
log_id.to_s,
{
@ -21,20 +22,20 @@ class CustomWizard::Log
}
)
end
def self.list_query
PluginStoreRow.where("
plugin_name = 'custom_wizard_log' AND
(value::json->'date') IS NOT NULL
").order("value::json->>'date' DESC")
end
def self.list(page = 0, limit = nil)
limit = limit.to_i > 0 ? limit.to_i : PAGE_LIMIT
page = page.to_i
self.list_query.limit(limit)
.offset(page * limit)
.map { |r| self.new(JSON.parse(r.value)) }
end
end
end

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

@ -1,24 +1,24 @@
# frozen_string_literal: true
require_relative '../plugin_helper'
describe InvitesControllerCustomWizard, type: :request do
fab!(:topic) { Fabricate(:topic) }
let(:invite) do
Invite.invite_by_email("angus@email.com", topic.user, topic)
end
let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) }
let(:template) do
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
end
before do
@controller = InvitesController.new
end
it "redirects a user to wizard after invite if after signup is enabled" do
template['after_signup'] = true
CustomWizard::Template.save(template, skip_jobs: true)
put "/invites/show/#{invite.invite_key}.json"
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'
describe CustomWizardUsersController, type: :request do
@ -6,16 +7,16 @@ describe CustomWizardUsersController, type: :request do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
end
before do
@controller = UsersController.new
end
it "redirects a user to wizard after sign up if after signup is enabled" do
template['after_signup'] = true
CustomWizard::Template.save(template, skip_jobs: true)
sign_in(Fabricate(:user))
get "/u/account-created"
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'
describe CustomWizardFieldExtension do
@ -6,7 +7,7 @@ describe CustomWizardFieldExtension do
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/field.json"
).read).with_indifferent_access
end
it "adds custom field attributes" do
field = Wizard::Field.new(field_hash)
expect(field.id).to eq("field_id")
@ -17,5 +18,5 @@ describe CustomWizardFieldExtension do
expect(field.key).to eq("field.locale.key")
expect(field.type).to eq("field_type")
expect(field.content).to eq([])
end
end
end
end

Datei anzeigen

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

Datei anzeigen

@ -6,7 +6,7 @@ describe Jobs::ClearAfterTimeWizard do
fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) }
fab!(:user3) { Fabricate(:user) }
let(:template) {
JSON.parse(File.open(
"#{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["after_time"] = true
after_time_template["after_time_scheduled"] = (Time.now + 3.hours).iso8601
CustomWizard::Template.save(after_time_template)
Jobs::SetAfterTimeWizard.new.execute(wizard_id: 'super_mega_fun_wizard')
expect(
UserCustomField.where(
name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard'
).length
).to eq(3)
described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
expect(
UserCustomField.where("
name = 'redirect_to_wizard' AND
@ -38,4 +38,4 @@ describe Jobs::ClearAfterTimeWizard do
").exists?
).to eq(false)
end
end
end

Datei anzeigen

@ -6,7 +6,7 @@ describe Jobs::SetAfterTimeWizard do
fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) }
fab!(:user3) { Fabricate(:user) }
let(:template) {
JSON.parse(File.open(
"#{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["after_time"] = true
after_time_template["after_time_scheduled"] = (Time.now + 3.hours).iso8601
CustomWizard::Template.save(after_time_template)
messages = MessageBus.track_publish("/redirect_to_wizard") do
described_class.new.execute(wizard_id: 'super_mega_fun_wizard')
end
expect(
UserCustomField.where(
name: 'redirect_to_wizard',
value: 'super_mega_fun_wizard'
).length
).to eq(3)
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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

@ -4,7 +4,7 @@ require_relative '../../plugin_helper'
describe CustomWizard::BasicWizardSerializer do
fab!(:user) { Fabricate(:user) }
it 'should return basic wizard attributes' do
CustomWizard::Template.save(
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][:name]).to eq("Super Mega Fun Wizard")
end
end
end

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

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