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

Add enabled setting && tests && file restructure

Dieser Commit ist enthalten in:
Angus McLeod 2019-12-05 17:48:32 +11:00
Ursprung bbfc5abae1
Commit f1fdc37a21
31 geänderte Dateien mit 597 neuen und 510 gelöschten Zeilen

Datei anzeigen

@ -3,7 +3,11 @@ import DiscourseURL from 'discourse/lib/url';
export default { export default {
name: 'custom-wizard-edits', name: 'custom-wizard-edits',
initialize() { initialize(container) {
const siteSettings = container.lookup('site-settings:main');
if (!siteSettings.custom_wizard_enabled) return;
withPluginApi('0.8.12', api => { withPluginApi('0.8.12', api => {
api.modifyClass('component:global-notice', { api.modifyClass('component:global-notice', {
buildBuffer(buffer) { buildBuffer(buffer) {

Datei anzeigen

@ -6,8 +6,9 @@ export default {
initialize: function (container) { initialize: function (container) {
const messageBus = container.lookup('message-bus:main'); const messageBus = container.lookup('message-bus:main');
const siteSettings = container.lookup('site-settings:main');
if (!messageBus) { return; }
if (!siteSettings.custom_wizard_enabled || !messageBus) return;
messageBus.subscribe("/redirect_to_wizard", function (wizardId) { messageBus.subscribe("/redirect_to_wizard", function (wizardId) {
const wizardUrl = window.location.origin + '/w/' + wizardId; const wizardUrl = window.location.origin + '/w/' + wizardId;

Datei anzeigen

@ -21,6 +21,7 @@ en:
no_valid_wizards: "File doesn't contain any valid wizards" no_valid_wizards: "File doesn't contain any valid wizards"
site_settings: site_settings:
custom_wizard_enabled: "Enable custom wizards."
wizard_redirect_exclude_paths: "Routes excluded from wizard redirects." wizard_redirect_exclude_paths: "Routes excluded from wizard redirects."
wizard_recognised_image_upload_formats: "File types which will result in upload displaying an image preview" wizard_recognised_image_upload_formats: "File types which will result in upload displaying an image preview"
wizard_national_flags_label_cue: "The characters that must appear in the dropdown field label for it to show a flag" wizard_national_flags_label_cue: "The characters that must appear in the dropdown field label for it to show a flag"

36
config/routes.rb Normale Datei
Datei anzeigen

@ -0,0 +1,36 @@
CustomWizard::Engine.routes.draw do
get ':wizard_id' => 'wizard#index'
put ':wizard_id/skip' => 'wizard#skip'
get ':wizard_id/steps' => 'wizard#index'
get ':wizard_id/steps/:step_id' => 'wizard#index'
put ':wizard_id/steps/:step_id' => 'steps#update'
end
Discourse::Application.routes.append do
mount ::CustomWizard::Engine, at: 'w'
post 'wizard/authorization/callback' => "custom_wizard/authorization#callback"
scope module: 'custom_wizard', constraints: AdminConstraint.new do
get 'admin/wizards' => 'admin#index'
get 'admin/wizards/field-types' => 'admin#field_types'
get 'admin/wizards/custom' => 'admin#index'
get 'admin/wizards/custom/new' => 'admin#index'
get 'admin/wizards/custom/all' => 'admin#custom_wizards'
get 'admin/wizards/custom/:wizard_id' => 'admin#find_wizard'
put 'admin/wizards/custom/save' => 'admin#save'
delete 'admin/wizards/custom/remove' => 'admin#remove'
get 'admin/wizards/submissions' => 'admin#index'
get 'admin/wizards/submissions/:wizard_id' => 'admin#submissions'
get 'admin/wizards/apis' => 'api#list'
get 'admin/wizards/apis/new' => 'api#index'
get 'admin/wizards/apis/:name' => 'api#find'
put 'admin/wizards/apis/:name' => 'api#save'
delete 'admin/wizards/apis/:name' => 'api#remove'
delete 'admin/wizards/apis/logs/:name' => 'api#clearlogs'
get 'admin/wizards/apis/:name/redirect' => 'api#redirect'
get 'admin/wizards/apis/:name/authorize' => 'api#authorize'
get 'admin/wizards/transfer' => 'transfer#index'
get 'admin/wizards/transfer/export' => 'transfer#export'
post 'admin/wizards/transfer/import' => 'transfer#import'
end
end

Datei anzeigen

@ -1,4 +1,5 @@
plugins: plugins:
custom_wizard_enabled: true
wizard_redirect_exclude_paths: wizard_redirect_exclude_paths:
client: true client: true
type: list type: list

Datei anzeigen

@ -77,112 +77,118 @@ class CustomWizard::Builder
end end
def build(build_opts = {}, params = {}) def build(build_opts = {}, params = {})
unless (@wizard.completed? && !@wizard.multiple_submissions && !@wizard.user.admin) || !@steps || !@wizard.permitted?
reset_submissions if build_opts[:reset] return @wizard if !SiteSetting.custom_wizard_enabled ||
(!@wizard.multiple_submissions &&
@wizard.completed? &&
!@wizard.user.admin) ||
!@steps ||
!@wizard.permitted?
reset_submissions if build_opts[:reset]
@steps.each do |step_template| @steps.each do |step_template|
@wizard.append_step(step_template['id']) do |step| @wizard.append_step(step_template['id']) do |step|
step.title = step_template['title'] if step_template['title'] step.title = step_template['title'] if step_template['title']
step.description = step_template['description'] if step_template['description'] step.description = step_template['description'] if step_template['description']
step.banner = step_template['banner'] if step_template['banner'] step.banner = step_template['banner'] if step_template['banner']
step.key = step_template['key'] if step_template['key'] step.key = step_template['key'] if step_template['key']
step.permitted = true step.permitted = true
if permitted_params = step_template['permitted_params'] if permitted_params = step_template['permitted_params']
permitted_data = {} permitted_data = {}
permitted_params.each do |param| permitted_params.each do |param|
key = param['key'].to_sym key = param['key'].to_sym
permitted_data[key] = params[key] if params[key] permitted_data[key] = params[key] if params[key]
end
if permitted_data.present?
current_data = @submissions.last || {}
save_submissions(current_data.merge(permitted_data), false)
end
end end
if required_data = step_template['required_data'] if permitted_data.present?
if !@submissions.last && required_data.present? current_data = @submissions.last || {}
step.permitted = false save_submissions(current_data.merge(permitted_data), false)
next end
end end
required_data.each do |rd| if required_data = step_template['required_data']
if rd['connector'] === 'equals' if !@submissions.last && required_data.present?
step.permitted = @submissions.last[rd['key']] == @submissions.last[rd['value']] step.permitted = false
end next
end
if !step.permitted
step.permitted_message = step_template['required_data_message'] if step_template['required_data_message']
next
end
end end
required_data.each do |rd|
if rd['connector'] === 'equals'
step.permitted = @submissions.last[rd['key']] == @submissions.last[rd['value']]
end
end
if !step.permitted
step.permitted_message = step_template['required_data_message'] if step_template['required_data_message']
next
end
end
if step_template['fields'] && step_template['fields'].length
step_template['fields'].each do |field_template|
append_field(step, step_template, field_template, build_opts)
end
end
step.on_update do |updater|
@updater = updater
user = @wizard.user
if step_template['fields'] && step_template['fields'].length if step_template['fields'] && step_template['fields'].length
step_template['fields'].each do |field_template| step_template['fields'].each do |field|
append_field(step, step_template, field_template, build_opts) validate_field(field, updater, step_template) if field['type'] != 'text-only'
end
end
next if updater.errors.any?
CustomWizard::Builder.step_handlers.each do |handler|
if handler[:wizard_id] == @wizard.id
handler[:block].call(self)
end end
end end
step.on_update do |updater| next if updater.errors.any?
@updater = updater
user = @wizard.user data = updater.fields.to_h
if step_template['fields'] && step_template['fields'].length ## if the wizard has data from the previous steps make that accessible to the actions.
step_template['fields'].each do |field| if @submissions && @submissions.last && !@submissions.last.key?("submitted_at")
validate_field(field, updater, step_template) if field['type'] != 'text-only' submission = @submissions.last
end data = submission.merge(data)
end
if step_template['actions'] && step_template['actions'].length && data
step_template['actions'].each do |action|
self.send(action['type'].to_sym, user, action, data)
end end
end
next if updater.errors.any?
CustomWizard::Builder.step_handlers.each do |handler| final_step = updater.step.next.nil?
if handler[:wizard_id] == @wizard.id
handler[:block].call(self) if route_to = data['route_to']
end data.delete('route_to')
end end
next if updater.errors.any? if @wizard.save_submissions && updater.errors.empty?
save_submissions(data, final_step)
elsif final_step
PluginStore.remove("#{@wizard.id}_submissions", @wizard.user.id)
end
data = updater.fields.to_h if final_step && @wizard.id === @wizard.user.custom_fields['redirect_to_wizard']
@wizard.user.custom_fields.delete('redirect_to_wizard');
@wizard.user.save_custom_fields(true)
end
## if the wizard has data from the previous steps make that accessible to the actions. if updater.errors.empty?
if @submissions && @submissions.last && !@submissions.last.key?("submitted_at") if final_step
submission = @submissions.last updater.result[:redirect_on_complete] = route_to || data['redirect_on_complete']
data = submission.merge(data) elsif route_to
end updater.result[:redirect_on_next] = route_to
if step_template['actions'] && step_template['actions'].length && data
step_template['actions'].each do |action|
self.send(action['type'].to_sym, user, action, data)
end
end
final_step = updater.step.next.nil?
if route_to = data['route_to']
data.delete('route_to')
end
if @wizard.save_submissions && updater.errors.empty?
save_submissions(data, final_step)
elsif final_step
PluginStore.remove("#{@wizard.id}_submissions", @wizard.user.id)
end
if final_step && @wizard.id === @wizard.user.custom_fields['redirect_to_wizard']
@wizard.user.custom_fields.delete('redirect_to_wizard');
@wizard.user.save_custom_fields(true)
end
if updater.errors.empty?
if final_step
updater.result[:redirect_on_complete] = route_to || data['redirect_on_complete']
elsif route_to
updater.result[:redirect_on_next] = route_to
end
end end
end end
end end

6
lib/custom_wizard/engine.rb Normale Datei
Datei anzeigen

@ -0,0 +1,6 @@
module ::CustomWizard
class Engine < ::Rails::Engine
engine_name 'custom_wizard'
isolate_namespace CustomWizard
end
end

Datei anzeigen

@ -3,6 +3,8 @@ require_dependency 'wizard/field'
require_dependency 'wizard/step_updater' require_dependency 'wizard/step_updater'
require_dependency 'wizard/builder' require_dependency 'wizard/builder'
UserHistory.actions[:custom_wizard_step] = 1000
class CustomWizard::Wizard class CustomWizard::Wizard
attr_reader :steps, :user attr_reader :steps, :user

Datei anzeigen

@ -1,227 +0,0 @@
require_dependency 'wizard'
require_dependency 'wizard/field'
require_dependency 'wizard/step'
::Wizard.class_eval do
def self.user_requires_completion?(user)
wizard_result = self.new(user).requires_completion?
return wizard_result if wizard_result
custom_redirect = false
if user && user.first_seen_at.blank? && wizard_id = CustomWizard::Wizard.after_signup
wizard = CustomWizard::Wizard.create(user, wizard_id)
if !wizard.completed? && wizard.permitted?
custom_redirect = true
CustomWizard::Wizard.set_wizard_redirect(user, wizard_id)
end
end
!!custom_redirect
end
end
::Wizard::Field.class_eval do
attr_reader :label, :description, :image, :key, :min_length, :file_types, :limit, :property
attr_accessor :dropdown_none
def initialize(attrs)
@attrs = attrs || {}
@id = attrs[:id]
@type = attrs[:type]
@required = !!attrs[:required]
@description = attrs[:description]
@image = attrs[:image]
@key = attrs[:key]
@min_length = attrs[:min_length]
@value = attrs[:value]
@choices = []
@dropdown_none = attrs[:dropdown_none]
@file_types = attrs[:file_types]
@limit = attrs[:limit]
@property = attrs[:property]
end
def label
@label ||= PrettyText.cook(@attrs[:label])
end
end
::Wizard::Choice.class_eval do
def initialize(id, opts)
@id = id
@opts = opts
@data = opts[:data]
@extra_label = opts[:extra_label]
@icon = opts[:icon]
end
def label
@label ||= PrettyText.cook(@opts[:label])
end
end
class ::Wizard::Step
attr_accessor :title, :description, :key, :permitted, :permitted_message
end
::WizardSerializer.class_eval do
attributes :id,
:name,
:background,
:completed,
:required,
:min_trust,
:permitted,
:user,
:categories,
:uncategorized_category_id
def id
object.id
end
def include_id?
object.respond_to?(:id)
end
def name
object.name
end
def include_name?
object.respond_to?(:name)
end
def background
object.background
end
def include_background?
object.respond_to?(:background)
end
def completed
object.completed?
end
def include_completed?
object.completed? &&
(!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) &&
!scope.is_admin?
end
def min_trust
object.min_trust
end
def include_min_trust?
object.respond_to?(:min_trust)
end
def permitted
object.permitted?
end
def include_permitted?
object.respond_to?(:permitted?)
end
def include_start?
object.start && include_steps?
end
def include_steps?
!include_completed?
end
def required
object.required
end
def include_required?
object.respond_to?(:required)
end
def user
object.user
end
def categories
begin
site = ::Site.new(scope)
::ActiveModel::ArraySerializer.new(site.categories, each_serializer: BasicCategorySerializer)
rescue => e
puts "HERE IS THE ERROR: #{e.inspect}"
end
end
def uncategorized_category_id
SiteSetting.uncategorized_category_id
end
end
::WizardStepSerializer.class_eval do
attributes :permitted, :permitted_message
def title
return PrettyText.cook(object.title) if object.title
PrettyText.cook(I18n.t("#{object.key || i18n_key}.title", default: ''))
end
def description
return object.description if object.description
PrettyText.cook(I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url))
end
def permitted
object.permitted
end
def permitted_message
object.permitted_message
end
end
::WizardFieldSerializer.class_eval do
attributes :dropdown_none, :image, :file_types, :limit, :property
def label
return object.label if object.label.present?
I18n.t("#{object.key || i18n_key}.label", default: '')
end
def description
return object.description if object.description.present?
I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url)
end
def image
object.image
end
def include_image?
object.image.present?
end
def placeholder
I18n.t("#{object.key || i18n_key}.placeholder", default: '')
end
def dropdown_none
object.dropdown_none
end
def file_types
object.file_types
end
def limit
object.limit
end
def property
object.property
end
end

310
plugin.rb
Datei anzeigen

@ -8,11 +8,12 @@ register_asset 'stylesheets/wizard_custom_admin.scss'
register_asset 'lib/jquery.timepicker.min.js' register_asset 'lib/jquery.timepicker.min.js'
register_asset 'lib/jquery.timepicker.scss' register_asset 'lib/jquery.timepicker.scss'
enabled_site_setting :custom_wizard_enabled
config = Rails.application.config config = Rails.application.config
config.assets.paths << Rails.root.join('plugins', 'discourse-custom-wizard', 'assets', 'javascripts') config.assets.paths << Rails.root.join('plugins', 'discourse-custom-wizard', 'assets', 'javascripts')
config.assets.paths << Rails.root.join('plugins', 'discourse-custom-wizard', 'assets', 'stylesheets', 'wizard') config.assets.paths << Rails.root.join('plugins', 'discourse-custom-wizard', 'assets', 'stylesheets', 'wizard')
if Rails.env.production? if Rails.env.production?
config.assets.precompile += %w{ config.assets.precompile += %w{
wizard-custom-guest.js wizard-custom-guest.js
@ -35,79 +36,260 @@ if respond_to?(:register_svg_icon)
end end
after_initialize do after_initialize do
UserHistory.actions[:custom_wizard_step] = 1000 [
'../lib/custom_wizard/engine.rb',
'../config/routes.rb',
'../controllers/custom_wizard/wizard.rb',
'../controllers/custom_wizard/steps.rb',
'../controllers/custom_wizard/admin.rb',
'../controllers/custom_wizard/transfer.rb',
'../controllers/custom_wizard/api.rb',
'../jobs/clear_after_time_wizard.rb',
'../jobs/refresh_api_access_token.rb',
'../jobs/set_after_time_wizard.rb',
'../lib/custom_wizard/builder.rb',
'../lib/custom_wizard/field.rb',
'../lib/custom_wizard/flags.rb',
'../lib/custom_wizard/step_updater.rb',
'../lib/custom_wizard/template.rb',
'../lib/custom_wizard/wizard.rb',
'../lib/custom_wizard/api/api.rb',
'../lib/custom_wizard/api/authorization.rb',
'../lib/custom_wizard/api/endpoint.rb',
'../lib/custom_wizard/api/log_entry.rb',
'../serializers/custom_wizard/api_serializer.rb',
'../serializers/custom_wizard/basic_api_serializer.rb',
'../serializers/custom_wizard/api/authorization_serializer.rb',
'../serializers/custom_wizard/api/basic_endpoint_serializer.rb',
'../serializers/custom_wizard/api/endpoint_serializer.rb',
'../serializers/custom_wizard/api/log_serializer.rb'
].each do |path|
load File.expand_path(path, __FILE__)
end
::Wizard.class_eval do
def self.user_requires_completion?(user)
wizard_result = self.new(user).requires_completion?
return wizard_result if wizard_result
module ::CustomWizard custom_redirect = false
class Engine < ::Rails::Engine
engine_name 'custom_wizard' if user && user.first_seen_at.blank? && wizard_id = CustomWizard::Wizard.after_signup
isolate_namespace CustomWizard wizard = CustomWizard::Wizard.create(user, wizard_id)
if !wizard.completed? && wizard.permitted?
custom_redirect = true
CustomWizard::Wizard.set_wizard_redirect(user, wizard_id)
end
end
!!custom_redirect
end end
end end
CustomWizard::Engine.routes.draw do ::Wizard::Field.class_eval do
get ':wizard_id' => 'wizard#index' attr_reader :label, :description, :image, :key, :min_length, :file_types, :limit, :property
put ':wizard_id/skip' => 'wizard#skip' attr_accessor :dropdown_none
get ':wizard_id/steps' => 'wizard#index'
get ':wizard_id/steps/:step_id' => 'wizard#index'
put ':wizard_id/steps/:step_id' => 'steps#update'
end
Discourse::Application.routes.append do def initialize(attrs)
mount ::CustomWizard::Engine, at: 'w' @attrs = attrs || {}
post 'wizard/authorization/callback' => "custom_wizard/authorization#callback" @id = attrs[:id]
@type = attrs[:type]
@required = !!attrs[:required]
@description = attrs[:description]
@image = attrs[:image]
@key = attrs[:key]
@min_length = attrs[:min_length]
@value = attrs[:value]
@choices = []
@dropdown_none = attrs[:dropdown_none]
@file_types = attrs[:file_types]
@limit = attrs[:limit]
@property = attrs[:property]
end
scope module: 'custom_wizard', constraints: AdminConstraint.new do def label
get 'admin/wizards' => 'admin#index' @label ||= PrettyText.cook(@attrs[:label])
get 'admin/wizards/field-types' => 'admin#field_types'
get 'admin/wizards/custom' => 'admin#index'
get 'admin/wizards/custom/new' => 'admin#index'
get 'admin/wizards/custom/all' => 'admin#custom_wizards'
get 'admin/wizards/custom/:wizard_id' => 'admin#find_wizard'
put 'admin/wizards/custom/save' => 'admin#save'
delete 'admin/wizards/custom/remove' => 'admin#remove'
get 'admin/wizards/submissions' => 'admin#index'
get 'admin/wizards/submissions/:wizard_id' => 'admin#submissions'
get 'admin/wizards/apis' => 'api#list'
get 'admin/wizards/apis/new' => 'api#index'
get 'admin/wizards/apis/:name' => 'api#find'
put 'admin/wizards/apis/:name' => 'api#save'
delete 'admin/wizards/apis/:name' => 'api#remove'
delete 'admin/wizards/apis/logs/:name' => 'api#clearlogs'
get 'admin/wizards/apis/:name/redirect' => 'api#redirect'
get 'admin/wizards/apis/:name/authorize' => 'api#authorize'
get 'admin/wizards/transfer' => 'transfer#index'
get 'admin/wizards/transfer/export' => 'transfer#export'
post 'admin/wizards/transfer/import' => 'transfer#import'
end end
end end
load File.expand_path('../jobs/clear_after_time_wizard.rb', __FILE__) ::Wizard::Choice.class_eval do
load File.expand_path('../jobs/set_after_time_wizard.rb', __FILE__) def initialize(id, opts)
load File.expand_path('../lib/builder.rb', __FILE__) @id = id
load File.expand_path('../lib/field.rb', __FILE__) @opts = opts
load File.expand_path('../lib/flags.rb', __FILE__) @data = opts[:data]
load File.expand_path('../lib/step_updater.rb', __FILE__) @extra_label = opts[:extra_label]
load File.expand_path('../lib/template.rb', __FILE__) @icon = opts[:icon]
load File.expand_path('../lib/wizard.rb', __FILE__) end
load File.expand_path('../lib/wizard_edits.rb', __FILE__)
load File.expand_path('../controllers/wizard.rb', __FILE__)
load File.expand_path('../controllers/steps.rb', __FILE__)
load File.expand_path('../controllers/admin.rb', __FILE__)
#transfer code
load File.expand_path('../controllers/transfer.rb', __FILE__)
load File.expand_path('../jobs/refresh_api_access_token.rb', __FILE__) def label
load File.expand_path('../lib/api/api.rb', __FILE__) @label ||= PrettyText.cook(@opts[:label])
load File.expand_path('../lib/api/authorization.rb', __FILE__) end
load File.expand_path('../lib/api/endpoint.rb', __FILE__) end
load File.expand_path('../lib/api/log_entry.rb', __FILE__)
load File.expand_path('../controllers/api.rb', __FILE__) class ::Wizard::Step
load File.expand_path('../serializers/api/api_serializer.rb', __FILE__) attr_accessor :title, :description, :key, :permitted, :permitted_message
load File.expand_path('../serializers/api/authorization_serializer.rb', __FILE__) end
load File.expand_path('../serializers/api/basic_api_serializer.rb', __FILE__)
load File.expand_path('../serializers/api/endpoint_serializer.rb', __FILE__) ::WizardSerializer.class_eval do
load File.expand_path('../serializers/api/basic_endpoint_serializer.rb', __FILE__) attributes :id,
load File.expand_path('../serializers/api/log_serializer.rb', __FILE__) :name,
:background,
:completed,
:required,
:min_trust,
:permitted,
:user,
:categories,
:uncategorized_category_id
def id
object.id
end
def include_id?
object.respond_to?(:id)
end
def name
object.name
end
def include_name?
object.respond_to?(:name)
end
def background
object.background
end
def include_background?
object.respond_to?(:background)
end
def completed
object.completed?
end
def include_completed?
object.completed? &&
(!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) &&
!scope.is_admin?
end
def min_trust
object.min_trust
end
def include_min_trust?
object.respond_to?(:min_trust)
end
def permitted
object.permitted?
end
def include_permitted?
object.respond_to?(:permitted?)
end
def include_start?
object.start && include_steps?
end
def include_steps?
!include_completed?
end
def required
object.required
end
def include_required?
object.respond_to?(:required)
end
def user
object.user
end
def categories
begin
site = ::Site.new(scope)
::ActiveModel::ArraySerializer.new(site.categories, each_serializer: BasicCategorySerializer)
rescue => e
puts "HERE IS THE ERROR: #{e.inspect}"
end
end
def uncategorized_category_id
SiteSetting.uncategorized_category_id
end
end
::WizardStepSerializer.class_eval do
attributes :permitted, :permitted_message
def title
return PrettyText.cook(object.title) if object.title
PrettyText.cook(I18n.t("#{object.key || i18n_key}.title", default: ''))
end
def description
return object.description if object.description
PrettyText.cook(I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url))
end
def permitted
object.permitted
end
def permitted_message
object.permitted_message
end
end
::WizardFieldSerializer.class_eval do
attributes :dropdown_none, :image, :file_types, :limit, :property
def label
return object.label if object.label.present?
I18n.t("#{object.key || i18n_key}.label", default: '')
end
def description
return object.description if object.description.present?
I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url)
end
def image
object.image
end
def include_image?
object.image.present?
end
def placeholder
I18n.t("#{object.key || i18n_key}.placeholder", default: '')
end
def dropdown_none
object.dropdown_none
end
def file_types
object.file_types
end
def limit
object.limit
end
def property
object.property
end
end
::UsersController.class_eval do ::UsersController.class_eval do
def wizard_path def wizard_path

Datei anzeigen

@ -3,156 +3,179 @@
require 'rails_helper' require 'rails_helper'
describe CustomWizard::Builder do describe CustomWizard::Builder do
it "returns a wizard when enabled" do fab!(:user) { Fabricate(:user) }
## implement enabled site setting first
before do
@template = File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read
end end
it "returns nothing when disabled" do it "returns no steps when disabled" do
## implement enabled site setting first CustomWizard::Wizard.add_wizard(@template)
SiteSetting.custom_wizard_enabled = false
wizard = CustomWizard::Builder.new(user, 'welcome').build
expect(wizard.steps.length).to eq(0)
expect(wizard.name).to eq('Welcome')
end end
it 'returns a wizard with prefilled data if user has partially completed' do context 'enabled' do
before do
end SiteSetting.custom_wizard_enabled = true
end
it 'returns a wiard with no prefilled data if options include reset' do
end
it 'returns nothing if the multiple submissions are disabled and user has completed' do
end it "returns steps when enabled" do
CustomWizard::Wizard.add_wizard(@template)
it 'returns nothing if the user is not permitted to see it' do wizard = CustomWizard::Builder.new(user, 'welcome').build
expect(wizard.steps.length).to eq(2)
end end
context 'building steps' do it 'returns no steps if the multiple submissions are disabled and user has completed' do
it 'returns step data correctly' do @template['multiple_submissions'] = false
CustomWizard::Wizard.add_wizard(@template)
wizard = CustomWizard::Builder.new(user, 'welcome').build
expect(wizard.steps.length).to eq(0)
end
it 'returns nothing if the user is not permitted to see it' do
end
it 'returns a wizard with prefilled data if user has partially completed' do
end
it 'returns a wizard with no prefilled data if options include reset' do
end
context 'building steps' do
it 'returns step data correctly' do
end
end it 'saves permitted params' do
it 'saves permitted params' do
end
it 'ensures required data is present' do
end
end
context 'building fields' do
it 'returns field data correctly' do
end
it 'returns checkbox fields correctly' do
end
it 'returns upload fields correctly' do
end
it 'returns category fields correctly' do
end
it 'returns tag fields correctly' do
end
it 'returns custom dropdown fields correctly' do
end
it 'returns translated dropdown fields correctly' do
end
it 'returns preset dropdown fields correctly' do
end
it 'applies preset dropdown filters correctly' do
end
it 'prefils profile data correctly' do
end
end
context 'on update' do
context 'validation' do
it 'applies min length correctly' do
end end
it 'standardises boolean entries' do it 'ensures required data is present' do
end
end
context 'building fields' do
it 'returns field data correctly' do
end end
it 'requires required fields' do it 'returns checkbox fields correctly' do
## this may require additional work?
end end
context 'submisisons' do it 'returns upload fields correctly' do
it 'saves submissions' do
end
it 'returns category fields correctly' do
end
it 'returns tag fields correctly' do
end
it 'returns custom dropdown fields correctly' do
end
it 'returns translated dropdown fields correctly' do
end
it 'returns preset dropdown fields correctly' do
end
it 'applies preset dropdown filters correctly' do
end
it 'prefils profile data correctly' do
end
end
context 'on update' do
context 'validation' do
it 'applies min length correctly' do
end end
it "doesn't save submissions if disabled" do it 'standardises boolean entries' do
end
it 'requires required fields' do
## this may require additional work?
end
context 'submisisons' do
it 'saves submissions' do
end
it "doesn't save submissions if disabled" do
end
end
end
context 'custom_step_handlers' do
it 'runs custom step handlers' do
end end
end end
end
context 'custom_step_handlers' do
it 'runs custom step handlers' do
end context 'actions' do
end it 'runs all actions attached to a step' do
context 'actions' do end
it 'runs all actions attached to a step' do
end it 'interpolates wizard and user data correctly' do
it 'interpolates wizard and user data correctly' do
end
it 'creates a topic' do
end
it 'sends a message' do
end
it 'doesnt sent a message if the required data is not present' do
end
it 'updates a profile' do
end
it 'calls an api' do
end
it 'opens a composer' do
end
it 'adds a user to a group' do
end
it 're-routes a user' do
end
it 'creates a topic' do
end
it 'sends a message' do
end
it 'doesnt sent a message if the required data is not present' do
end
it 'updates a profile' do
end
it 'calls an api' do
end
it 'opens a composer' do
end
it 'adds a user to a group' do
end
it 're-routes a user' do
end
end end
end end
end end

52
spec/fixtures/wizard.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,52 @@
{
"id": "welcome",
"name": "Welcome",
"background": "#006da3",
"save_submissions": true,
"multiple_submissions": true,
"after_signup": true,
"theme_id": 4,
"steps": [
{
"id": "step_1",
"title": "Welcome to Pavilion",
"raw_description": "Hey there, thanks for signing up.\n\nWe're Pavilion, an international freelancer cooperative that specialises in online communities.\n\nThis site is our own community, where we work with our clients, users of our open source work and our broader community.\n\n",
"description": "<p>Hey there, thanks for signing up.</p>\n<p>Were Pavilion, an international freelancer cooperative that specialises in online communities.</p>\n<p>This site is our own community, where we work with our clients, users of our open source work and our broader community.</p>"
},
{
"id": "step_2",
"title": "Tell us about you",
"raw_description": "We'd like to know a little more about you. Add a your name and your website below. This will update your user profile.",
"fields": [
{
"id": "name",
"type": "text",
"label": "Name",
"required": true
},
{
"id": "field_3",
"label": "Website",
"type": "text"
}
],
"actions": [
{
"id": "update_profile",
"type": "update_profile",
"profile_updates": [
{
"key": "name",
"value": "name"
},
{
"key": "field_3",
"value": "website"
}
]
}
],
"description": "<p>Wed like to know a little more about you. Add a your name and your website below. This will update your user profile.</p>"
}
]
}