Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-22 09:20:29 +01:00
wip
Dieser Commit ist enthalten in:
Ursprung
94c56ef550
Commit
8fdd263d8e
16 geänderte Dateien mit 859 neuen und 286 gelöschten Zeilen
|
@ -113,6 +113,7 @@
|
||||||
wizardFieldSelection=true
|
wizardFieldSelection=true
|
||||||
userFieldSelection='key,value'
|
userFieldSelection='key,value'
|
||||||
categorySelection='output'
|
categorySelection='output'
|
||||||
|
wizardActionSelection='output'
|
||||||
outputDefaultSelection='category'
|
outputDefaultSelection='category'
|
||||||
context='action'
|
context='action'
|
||||||
)}}
|
)}}
|
||||||
|
@ -198,6 +199,7 @@
|
||||||
textSelection='value'
|
textSelection='value'
|
||||||
userFieldSelection='key'
|
userFieldSelection='key'
|
||||||
wizardFieldSelection='value'
|
wizardFieldSelection='value'
|
||||||
|
wizardActionSelection='value'
|
||||||
keyDefaultSelection='userField'
|
keyDefaultSelection='userField'
|
||||||
context='action'
|
context='action'
|
||||||
)}}
|
)}}
|
||||||
|
@ -270,6 +272,7 @@
|
||||||
textSelection='value,output'
|
textSelection='value,output'
|
||||||
wizardFieldSelection='key,value,assignment'
|
wizardFieldSelection='key,value,assignment'
|
||||||
userFieldSelection='key,value,assignment'
|
userFieldSelection='key,value,assignment'
|
||||||
|
wizardActionSelection=true
|
||||||
groupSelection='value,output'
|
groupSelection='value,output'
|
||||||
outputDefaultSelection='group'
|
outputDefaultSelection='group'
|
||||||
context='action'
|
context='action'
|
||||||
|
|
|
@ -11,11 +11,11 @@ class CustomWizard::StepsController < ::ApplicationController
|
||||||
permitted[:fields] = params[:fields].select { |k, v| field_ids.include? k }
|
permitted[:fields] = params[:fields].select { |k, v| field_ids.include? k }
|
||||||
permitted.permit!
|
permitted.permit!
|
||||||
end
|
end
|
||||||
|
|
||||||
wizard = CustomWizard::Builder.new(permitted[:wizard_id].underscore, current_user).build
|
wizard = CustomWizard::Builder.new(permitted[:wizard_id].underscore, current_user).build
|
||||||
updater = wizard.create_updater(permitted[:step_id], permitted[:fields])
|
updater = wizard.create_updater(permitted[:step_id], permitted[:fields])
|
||||||
updater.update
|
updater.update
|
||||||
|
|
||||||
if updater.success?
|
if updater.success?
|
||||||
result = success_json
|
result = success_json
|
||||||
result.merge!(updater.result) if updater.result
|
result.merge!(updater.result) if updater.result
|
||||||
|
|
|
@ -77,6 +77,11 @@ class CustomWizard::Action
|
||||||
multiple: true
|
multiple: true
|
||||||
).perform
|
).perform
|
||||||
|
|
||||||
|
if targets.blank?
|
||||||
|
log_error("no recipients", "send_message has no recipients")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
targets.each do |target|
|
targets.each do |target|
|
||||||
if Group.find_by(name: target)
|
if Group.find_by(name: target)
|
||||||
params[:target_group_names] = target
|
params[:target_group_names] = target
|
||||||
|
@ -119,12 +124,18 @@ class CustomWizard::Action
|
||||||
|
|
||||||
def update_profile
|
def update_profile
|
||||||
params = {}
|
params = {}
|
||||||
|
|
||||||
if (profile_updates = action['profile_updates'])
|
if (profile_updates = action['profile_updates'])
|
||||||
profile_updates.first[:pairs].each do |pair|
|
profile_updates.first[:pairs].each do |pair|
|
||||||
if allowed_profile_field?(pair['key'])
|
if allowed_profile_field?(pair['key'])
|
||||||
key = cast_profile_key(pair['key'])
|
key = cast_profile_key(pair['key'])
|
||||||
value = cast_profile_value(mapper.map_field(pair['value'], pair['value_type']), pair['key'])
|
value = cast_profile_value(
|
||||||
|
mapper.map_field(
|
||||||
|
pair['value'],
|
||||||
|
pair['value_type']
|
||||||
|
),
|
||||||
|
pair['key']
|
||||||
|
)
|
||||||
|
|
||||||
if user_field?(pair['key'])
|
if user_field?(pair['key'])
|
||||||
params[:custom_fields] ||= {}
|
params[:custom_fields] ||= {}
|
||||||
|
@ -137,10 +148,10 @@ class CustomWizard::Action
|
||||||
end
|
end
|
||||||
|
|
||||||
params = add_custom_fields(params)
|
params = add_custom_fields(params)
|
||||||
|
|
||||||
if params.present?
|
if params.present?
|
||||||
result = UserUpdater.new(Discourse.system_user, user).update(params)
|
result = UserUpdater.new(Discourse.system_user, user).update(params)
|
||||||
|
|
||||||
if params[:avatar].present?
|
if params[:avatar].present?
|
||||||
result = update_avatar(params[:avatar])
|
result = update_avatar(params[:avatar])
|
||||||
end
|
end
|
||||||
|
@ -250,11 +261,11 @@ class CustomWizard::Action
|
||||||
|
|
||||||
def open_composer
|
def open_composer
|
||||||
params = basic_topic_params
|
params = basic_topic_params
|
||||||
|
|
||||||
if params[:title].present? && params[:raw].present?
|
if params[:title].present? && params[:raw].present?
|
||||||
url = "/new-topic?title=#{params[:title]}"
|
url = "/new-topic?title=#{params[:title]}"
|
||||||
url += "&body=#{params[:raw]}"
|
url += "&body=#{params[:raw]}"
|
||||||
|
|
||||||
if category_id = action_category
|
if category_id = action_category
|
||||||
if category_id && category = Category.find(category_id)
|
if category_id && category = Category.find(category_id)
|
||||||
url += "&category=#{category.full_slug('/')}"
|
url += "&category=#{category.full_slug('/')}"
|
||||||
|
@ -266,7 +277,7 @@ class CustomWizard::Action
|
||||||
end
|
end
|
||||||
|
|
||||||
route_to = Discourse.base_uri + URI.encode(url)
|
route_to = Discourse.base_uri + URI.encode(url)
|
||||||
data['redirect_on_complete'] = route_to
|
data['route_to'] = route_to
|
||||||
|
|
||||||
log_info("route: #{route_to}")
|
log_info("route: #{route_to}")
|
||||||
else
|
else
|
||||||
|
@ -283,8 +294,15 @@ class CustomWizard::Action
|
||||||
multiple: true
|
multiple: true
|
||||||
}
|
}
|
||||||
).perform
|
).perform
|
||||||
|
|
||||||
|
group_map = group_map.flatten.compact
|
||||||
|
|
||||||
|
unless group_map.present?
|
||||||
|
log_error("invalid group map")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
groups = group_map.flatten.reduce([]) do |groups, g|
|
groups = group_map.reduce([]) do |groups, g|
|
||||||
begin
|
begin
|
||||||
groups.push(Integer(g))
|
groups.push(Integer(g))
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
|
@ -324,7 +342,7 @@ class CustomWizard::Action
|
||||||
user: user
|
user: user
|
||||||
).perform
|
).perform
|
||||||
end
|
end
|
||||||
|
|
||||||
if action['code']
|
if action['code']
|
||||||
data[action['code']] = SecureRandom.hex(8)
|
data[action['code']] = SecureRandom.hex(8)
|
||||||
url += "&#{action['code']}=#{data[action['code']]}"
|
url += "&#{action['code']}=#{data[action['code']]}"
|
||||||
|
@ -336,20 +354,36 @@ class CustomWizard::Action
|
||||||
log_info("route: #{route_to}")
|
log_info("route: #{route_to}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_group
|
def create_group
|
||||||
group =
|
group =
|
||||||
begin
|
begin
|
||||||
Group.new(new_group_params)
|
Group.new(new_group_params.except(:usernames, :owner_usernames))
|
||||||
rescue ArgumentError => e
|
rescue ArgumentError => e
|
||||||
raise Discourse::InvalidParameters, "Invalid group params"
|
raise Discourse::InvalidParameters, "Invalid group params"
|
||||||
end
|
end
|
||||||
|
|
||||||
if group.save
|
if group.save
|
||||||
GroupActionLogger.new(user, group).log_change_group_settings
|
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) }
|
||||||
|
end
|
||||||
|
|
||||||
|
if new_group_params[:usernames].present?
|
||||||
|
user_ids = get_user_ids(new_group_params[:usernames])
|
||||||
|
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)
|
log_success("Group created", group.name)
|
||||||
|
|
||||||
result.output = group.name
|
result.output = group.name
|
||||||
else
|
else
|
||||||
log_error("Group creation failed")
|
log_error("Group creation failed", group.errors.messages)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -366,7 +400,7 @@ class CustomWizard::Action
|
||||||
log_success("Category created", category.name)
|
log_success("Category created", category.name)
|
||||||
result.output = category.id
|
result.output = category.id
|
||||||
else
|
else
|
||||||
log_error("Category creation failed")
|
log_error("Category creation failed", category.errors.messages)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -378,7 +412,7 @@ class CustomWizard::Action
|
||||||
data: data,
|
data: data,
|
||||||
user: user
|
user: user
|
||||||
).perform
|
).perform
|
||||||
|
|
||||||
if output.is_a?(Array)
|
if output.is_a?(Array)
|
||||||
output.first
|
output.first
|
||||||
elsif output.is_a?(Integer)
|
elsif output.is_a?(Integer)
|
||||||
|
@ -505,10 +539,12 @@ class CustomWizard::Action
|
||||||
user: user
|
user: user
|
||||||
).perform
|
).perform
|
||||||
|
|
||||||
value = value.parameterize(separator: '_') if attr === "name"
|
if value
|
||||||
value = value.to_i if attr.include?("_level")
|
value = value.parameterize(separator: '_') if attr === "name"
|
||||||
|
value = value.to_i if attr.include?("_level")
|
||||||
params[attr.to_sym] = value
|
|
||||||
|
params[attr.to_sym] = value
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -533,30 +569,36 @@ class CustomWizard::Action
|
||||||
user: user
|
user: user
|
||||||
).perform
|
).perform
|
||||||
|
|
||||||
if attr === "parent_category_id" && value.is_a?(Array)
|
if value
|
||||||
value = value[0]
|
if attr === "parent_category_id" && value.is_a?(Array)
|
||||||
end
|
value = value[0]
|
||||||
|
|
||||||
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
|
|
||||||
end
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if attr === 'slug'
|
||||||
|
value = value.parameterize(separator: '-')
|
||||||
|
end
|
||||||
|
|
||||||
|
params[attr.to_sym] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
params[attr.to_sym] = value
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -584,6 +626,8 @@ class CustomWizard::Action
|
||||||
end
|
end
|
||||||
|
|
||||||
def cast_profile_value(value, key)
|
def cast_profile_value(value, key)
|
||||||
|
return value if value.nil?
|
||||||
|
|
||||||
if profile_url_fields.include?(key)
|
if profile_url_fields.include?(key)
|
||||||
value['url']
|
value['url']
|
||||||
elsif key === 'avatar'
|
elsif key === 'avatar'
|
||||||
|
|
|
@ -133,7 +133,7 @@ class CustomWizard::Builder
|
||||||
validate_field(field, updater, step_template) if field['type'] != 'text_only'
|
validate_field(field, updater, step_template) if field['type'] != 'text_only'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
next if updater.errors.any?
|
next if updater.errors.any?
|
||||||
|
|
||||||
CustomWizard::Builder.step_handlers.each do |handler|
|
CustomWizard::Builder.step_handlers.each do |handler|
|
||||||
|
@ -156,10 +156,10 @@ class CustomWizard::Builder
|
||||||
|
|
||||||
if @actions.present?
|
if @actions.present?
|
||||||
@actions.each do |action|
|
@actions.each do |action|
|
||||||
|
|
||||||
if (action['run_after'] === updater.step.id) ||
|
if (action['run_after'] === updater.step.id) ||
|
||||||
(final_step && (!action['run_after'] || (action['run_after'] === 'wizard_completion')))
|
(final_step && (!action['run_after'] || (action['run_after'] === 'wizard_completion')))
|
||||||
|
|
||||||
CustomWizard::Action.new(
|
CustomWizard::Action.new(
|
||||||
wizard: @wizard,
|
wizard: @wizard,
|
||||||
action: action,
|
action: action,
|
||||||
|
@ -217,7 +217,7 @@ class CustomWizard::Builder
|
||||||
submission = @submissions.last
|
submission = @submissions.last
|
||||||
params[:value] = submission[field_template['id']] if submission[field_template['id']]
|
params[:value] = submission[field_template['id']] if submission[field_template['id']]
|
||||||
end
|
end
|
||||||
|
|
||||||
params[:value] = prefill_field(field_template, step_template) || params[:value]
|
params[:value] = prefill_field(field_template, step_template) || params[:value]
|
||||||
|
|
||||||
if field_template['type'] === 'group' && params[:value].present?
|
if field_template['type'] === 'group' && params[:value].present?
|
||||||
|
@ -339,7 +339,7 @@ class CustomWizard::Builder
|
||||||
if type === 'time' && value.present? && !validate_time(value)
|
if type === 'time' && value.present? && !validate_time(value)
|
||||||
updater.errors.add(id, I18n.t('wizard.field.invalid_time'))
|
updater.errors.add(id, I18n.t('wizard.field.invalid_time'))
|
||||||
end
|
end
|
||||||
|
|
||||||
CustomWizard::Builder.field_validators.each do |validator|
|
CustomWizard::Builder.field_validators.each do |validator|
|
||||||
if type === validator[:type]
|
if type === validator[:type]
|
||||||
validator[:block].call(field, updater, step_template)
|
validator[:block].call(field, updater, step_template)
|
||||||
|
|
|
@ -48,7 +48,7 @@ class CustomWizard::Mapper
|
||||||
inputs.each do |input|
|
inputs.each do |input|
|
||||||
input_type = input['type']
|
input_type = input['type']
|
||||||
pairs = input['pairs']
|
pairs = input['pairs']
|
||||||
|
|
||||||
if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment'
|
if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment'
|
||||||
output = input['output']
|
output = input['output']
|
||||||
output_type = input['output_type']
|
output_type = input['output_type']
|
||||||
|
|
|
@ -1,17 +1,27 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
describe CustomWizard::Action do
|
describe CustomWizard::Action do
|
||||||
let(:create_topic_action) {{"id":"create_topic","type":"create_topic","title":"text","post":"textarea"}}
|
fab!(:user) { Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com", trust_level: TrustLevel[2]) }
|
||||||
let(:send_message_action) {{"id":"send_message","type":"send_message","title":"text","post":"textarea","username":"angus"}}
|
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') }
|
||||||
let(:route_to_action) {{"id":"route_to","type":"route_to","url":"https://google.com"}}
|
fab!(:group) { Fabricate(:group) }
|
||||||
let(:open_composer_action) {{"id":"open_composer","type":"open_composer","title":"text","post":"textarea"}}
|
|
||||||
let(:add_to_group_action) {{"id":"add_to_group","type":"add_to_group","group_id":"dropdown_groups"}}
|
before do
|
||||||
|
Group.refresh_automatic_group!(:trust_level_2)
|
||||||
|
template = JSON.parse(File.open(
|
||||||
|
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
||||||
|
).read)
|
||||||
|
CustomWizard::Wizard.add_wizard(template)
|
||||||
|
@wizard = CustomWizard::Wizard.create('super_mega_fun_wizard', user)
|
||||||
|
end
|
||||||
|
|
||||||
it 'creates a topic' do
|
it 'creates a topic' do
|
||||||
template['steps'][0]['fields'] = [text_field, textarea_field]
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
template['steps'][0]["actions"] = [create_topic_action]
|
updater = built_wizard.create_updater(built_wizard.steps[0].id,
|
||||||
updater = run_update(template, nil,
|
step_1_field_1: "Topic Title",
|
||||||
text: "Topic Title",
|
step_1_field_2: "topic body"
|
||||||
textarea: "topic body"
|
).update
|
||||||
)
|
updater2 = built_wizard.create_updater(built_wizard.steps[1].id, {}).update
|
||||||
|
|
||||||
topic = Topic.where(title: "Topic Title")
|
topic = Topic.where(title: "Topic Title")
|
||||||
|
|
||||||
expect(topic.exists?).to eq(true)
|
expect(topic.exists?).to eq(true)
|
||||||
|
@ -22,71 +32,102 @@ describe CustomWizard::Action do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sends a message' do
|
it 'sends a message' do
|
||||||
fields = [text_field, textarea_field]
|
User.create(username: 'angus1', email: "angus1@email.com")
|
||||||
|
|
||||||
if extra_field
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
fields.push(extra_field)
|
built_wizard.create_updater(built_wizard.steps[0].id, {}).update
|
||||||
end
|
built_wizard.create_updater(built_wizard.steps[1].id, {}).update
|
||||||
|
|
||||||
template['steps'][0]['fields'] = fields
|
|
||||||
template['steps'][0]["actions"] = [send_message_action.merge(extra_action_opts)]
|
|
||||||
|
|
||||||
run_update(template, nil,
|
|
||||||
text: "Message Title",
|
|
||||||
textarea: "message body"
|
|
||||||
)
|
|
||||||
|
|
||||||
topic = Topic.where(
|
topic = Topic.where(
|
||||||
archetype: Archetype.private_message,
|
archetype: Archetype.private_message,
|
||||||
title: "Message Title"
|
title: "Message title"
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(topic.exists?).to eq(true)
|
post = Post.where(
|
||||||
expect(
|
|
||||||
topic.first.topic_allowed_users.first.user.username
|
|
||||||
).to eq('angus')
|
|
||||||
expect(Post.where(
|
|
||||||
topic_id: topic.pluck(:id),
|
topic_id: topic.pluck(:id),
|
||||||
raw: "message body"
|
raw: "I will interpolate some wizard fields"
|
||||||
).exists?).to eq(true)
|
)
|
||||||
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
it 'updates a profile' do
|
it 'updates a profile' do
|
||||||
run_update(template, template['steps'][1]['id'], name: "Sally")
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
expect(user.name).to eq('Sally')
|
upload = Upload.create!(
|
||||||
|
url: '/images/image.png',
|
||||||
|
original_filename: 'image.png',
|
||||||
|
filesize: 100,
|
||||||
|
user_id: -1,
|
||||||
|
)
|
||||||
|
steps = built_wizard.steps
|
||||||
|
built_wizard.create_updater(steps[0].id, {}).update
|
||||||
|
built_wizard.create_updater(steps[1].id,
|
||||||
|
step_2_field_7: upload.as_json,
|
||||||
|
).update
|
||||||
|
expect(user.profile_background_upload.id).to eq(upload.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'opens a composer' do
|
it 'opens a composer' do
|
||||||
template['steps'][0]['fields'] = [text_field, textarea_field]
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
template['steps'][0]["actions"] = [open_composer_action]
|
built_wizard.create_updater(built_wizard.steps[0].id, step_1_field_1: "Text input").update
|
||||||
|
|
||||||
updater = run_update(template, nil,
|
updater = built_wizard.create_updater(built_wizard.steps[1].id, {})
|
||||||
text: "Topic Title",
|
updater.update
|
||||||
textarea: "topic body"
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(updater.result.blank?).to eq(true)
|
submissions = PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
category = Category.find_by(id: submissions.first['action_8'])
|
||||||
|
|
||||||
updater = run_update(template, template['steps'][1]['id'])
|
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@email.com&category=#{category.slug}/#{category.id}&tags=tag1"
|
||||||
expect(updater.result[:redirect_on_complete]).to eq(
|
|
||||||
"/new-topic?title=Topic%20Title&body=topic%20body"
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds a user to a group' do
|
it 'creates a category' do
|
||||||
template['steps'][0]['fields'] = [dropdown_groups_field]
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
template['steps'][0]["actions"] = [add_to_group_action]
|
built_wizard.create_updater(built_wizard.steps[0].id, step_1_field_1: "Text input").update
|
||||||
|
built_wizard.create_updater(built_wizard.steps[1].id, {}).update
|
||||||
updater = run_update(template, nil, dropdown_groups: group.id)
|
submissions = PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
expect(Category.where(id: submissions.first['action_8']).exists?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a group' do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
step_id = built_wizard.steps[0].id
|
||||||
|
updater = built_wizard.create_updater(step_id, step_1_field_1: "Text input").update
|
||||||
|
submissions = PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
expect(Group.where(name: submissions.first['action_9']).exists?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds a user to a group' do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
step_id = built_wizard.steps[0].id
|
||||||
|
updater = built_wizard.create_updater(step_id, step_1_field_1: "Text input").update
|
||||||
|
submissions = PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
group = Group.find_by(name: submissions.first['action_9'])
|
||||||
expect(group.users.first.username).to eq('angus')
|
expect(group.users.first.username).to eq('angus')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'watches categories' do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
built_wizard.create_updater(built_wizard.steps[0].id, step_1_field_1: "Text input").update
|
||||||
|
built_wizard.create_updater(built_wizard.steps[1].id, {}).update
|
||||||
|
submissions = PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
expect(CategoryUser.where(
|
||||||
|
category_id: submissions.first['action_8'],
|
||||||
|
user_id: user.id
|
||||||
|
).first.notification_level).to eq(2)
|
||||||
|
expect(CategoryUser.where(
|
||||||
|
category_id: category.id,
|
||||||
|
user_id: user.id
|
||||||
|
).first.notification_level).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
it 're-routes a user' do
|
it 're-routes a user' do
|
||||||
template['steps'][0]["actions"] = [route_to_action]
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
updater = run_update(template, nil, {})
|
updater = built_wizard.create_updater(built_wizard.steps.last.id, {})
|
||||||
expect(updater.result[:redirect_on_next]).to eq(
|
updater.update
|
||||||
"https://google.com"
|
expect(updater.result[:redirect_on_complete]).to eq("https://google.com")
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,39 +3,19 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe CustomWizard::Builder do
|
describe CustomWizard::Builder do
|
||||||
fab!(:user) { Fabricate(:user, username: 'angus') }
|
fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[2]) }
|
||||||
fab!(:trusted_user) { Fabricate(:user, trust_level: 3) }
|
fab!(:new_user) { Fabricate(:user, trust_level: 0) }
|
||||||
fab!(:category1) { Fabricate(:category, name: 'cat1') }
|
fab!(:category1) { Fabricate(:category, name: 'cat1') }
|
||||||
fab!(:category2) { Fabricate(:category, name: 'cat2') }
|
fab!(:category2) { Fabricate(:category, name: 'cat2') }
|
||||||
fab!(:group) { Fabricate(:group) }
|
fab!(:group) { Fabricate(:group) }
|
||||||
|
|
||||||
let!(:template) do
|
before do
|
||||||
JSON.parse(File.open(
|
Group.refresh_automatic_group!(:trust_level_2)
|
||||||
|
template = JSON.parse(File.open(
|
||||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
||||||
).read)
|
).read)
|
||||||
end
|
CustomWizard::Wizard.add_wizard(template)
|
||||||
|
@wizard = CustomWizard::Wizard.create('super_mega_fun_wizard', user)
|
||||||
def build_wizard(t = template, u = user, build_opts = {}, params = {})
|
|
||||||
CustomWizard::Wizard.add_wizard(t)
|
|
||||||
CustomWizard::Builder.new('welcome', u).build(build_opts, params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_submission_data(data = {})
|
|
||||||
PluginStore.set("welcome_submissions", user.id, {
|
|
||||||
name: 'Angus',
|
|
||||||
website: 'https://thepavilion.io'
|
|
||||||
}.merge(data))
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_submission_data
|
|
||||||
PluginStore.get("welcome_submissions", user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def run_update(t = template, step_id = nil, data = {})
|
|
||||||
wizard = build_wizard(t)
|
|
||||||
updater = wizard.create_updater(step_id || t['steps'][0]['id'], data)
|
|
||||||
updater.update
|
|
||||||
updater
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'disabled' do
|
context 'disabled' do
|
||||||
|
@ -43,15 +23,8 @@ describe CustomWizard::Builder do
|
||||||
SiteSetting.custom_wizard_enabled = false
|
SiteSetting.custom_wizard_enabled = false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns no steps" do
|
it "returns nil" do
|
||||||
wizard = build_wizard
|
expect(CustomWizard::Builder.new(@wizard.id, user).build).to eq(nil)
|
||||||
expect(wizard.steps.length).to eq(0)
|
|
||||||
expect(wizard.name).to eq('Welcome')
|
|
||||||
end
|
|
||||||
|
|
||||||
it "doesn't save submissions" do
|
|
||||||
run_update(template, nil, name: 'Angus')
|
|
||||||
expect(get_submission_data.blank?).to eq(true)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,123 +34,164 @@ describe CustomWizard::Builder do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns steps" do
|
it "returns steps" do
|
||||||
expect(build_wizard.steps.length).to eq(2)
|
expect(
|
||||||
|
CustomWizard::Builder.new(@wizard.id, user).build.steps.length
|
||||||
|
).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns no steps if multiple submissions are disabled and user has completed' do
|
it 'returns no steps if multiple submissions are disabled and user has completed' do
|
||||||
|
wizard_template = CustomWizard::Wizard.find(@wizard.id)
|
||||||
|
wizard_template[:multiple_submissions] = false
|
||||||
|
CustomWizard::Wizard.save(wizard_template)
|
||||||
|
|
||||||
history_params = {
|
history_params = {
|
||||||
action: UserHistory.actions[:custom_wizard_step],
|
action: UserHistory.actions[:custom_wizard_step],
|
||||||
acting_user_id: user.id,
|
acting_user_id: user.id,
|
||||||
context: template['id']
|
context: @wizard.id
|
||||||
}
|
}
|
||||||
UserHistory.create!(history_params.merge(subject: template['steps'][0]['id']))
|
@wizard.steps.each do |step|
|
||||||
UserHistory.create!(history_params.merge(subject: template['steps'][1]['id']))
|
UserHistory.create!(history_params.merge(subject: step.id))
|
||||||
|
end
|
||||||
|
|
||||||
template["multiple_submissions"] = false
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
expect(build_wizard(template).steps.length).to eq(0)
|
expect(
|
||||||
|
CustomWizard::Builder.new(@wizard.id, user).build.steps.length
|
||||||
|
).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns no steps if user is not permitted' do
|
it 'returns no steps if user is not permitted' do
|
||||||
template["min_trust"] = 3
|
expect(
|
||||||
expect(build_wizard(template).steps.length).to eq(0)
|
CustomWizard::Builder.new(@wizard.id, new_user).build.steps.length
|
||||||
|
).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns steps if user is permitted' do
|
it 'returns steps if user is permitted' do
|
||||||
template["min_trust"] = 3
|
expect(
|
||||||
expect(build_wizard(template, trusted_user).steps.length).to eq(2)
|
CustomWizard::Builder.new(@wizard.id, user).build.steps.length
|
||||||
|
).to eq(3)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a wizard with prefilled data if user has partially completed it' do
|
it 'returns a wizard with prefilled data if user has partially completed it' do
|
||||||
add_submission_data
|
expect(
|
||||||
wizard = build_wizard
|
CustomWizard::Builder.new(@wizard.id, user)
|
||||||
expect(wizard.steps[0].fields.first.value).to eq('Angus')
|
.build
|
||||||
expect(wizard.steps[1].fields.first.value).to eq('https://thepavilion.io')
|
.steps[0].fields[0].value
|
||||||
|
).to eq('I am prefilled')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a wizard with no prefilled data if options include reset' do
|
it 'returns a wizard with no prefilled data if options include reset' do
|
||||||
add_submission_data
|
PluginStore.set("super_mega_fun_wizard_submissions", user.id, {
|
||||||
wizard = build_wizard(template, user, reset: true)
|
text: 'Input into text',
|
||||||
expect(wizard.steps[0].fields.first.value).to eq(nil)
|
})
|
||||||
expect(wizard.steps[1].fields.first.value).to eq(nil)
|
expect(
|
||||||
|
CustomWizard::Builder.new(@wizard.id, user)
|
||||||
|
.build(reset: true)
|
||||||
|
.steps[0].fields[0].value
|
||||||
|
).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'building steps' do
|
context 'building steps' do
|
||||||
it 'returns step metadata' do
|
it 'returns step metadata' do
|
||||||
expect(build_wizard.steps[0].title).to eq('Welcome to Pavilion')
|
expect(
|
||||||
expect(build_wizard.steps[1].title).to eq('Tell us about you')
|
CustomWizard::Builder.new(@wizard.id, user)
|
||||||
|
.build(reset: true)
|
||||||
|
.steps[0]
|
||||||
|
).to eq('Super Mega Fun Wizard')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'saves permitted params' do
|
it 'saves permitted params' do
|
||||||
template['steps'][0]['permitted_params'] = permitted_params
|
@wizard.steps[0].permitted_params = permitted_params
|
||||||
wizard = build_wizard(template, user, {}, param_key: 'param_value')
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build({}, param_key: 'param_value')
|
||||||
submissions = get_submission_data
|
submissions = PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
expect(submissions.first['submission_param_key']).to eq('param_value')
|
expect(submissions[0]['submission_param_key']).to eq('param_value')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is not permitted if required data is not present' do
|
it 'is not permitted if required data is not present' do
|
||||||
template['steps'][0]['required_data'] = required_data
|
@wizard.steps[0].required_data = required_data
|
||||||
expect(build_wizard(template, user).steps[0].permitted).to eq(false)
|
expect(
|
||||||
|
CustomWizard::Builder.new(@wizard.id, user).build.steps[0].permitted
|
||||||
|
).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'it shows required data message if required data has message' do
|
it 'it shows required data message if required data has message' do
|
||||||
template['steps'][0]['required_data'] = required_data
|
@wizard.steps[0].required_data = required_data
|
||||||
template['steps'][0]['required_data_message'] = required_data_message
|
@wizard.steps[0].required_data_message = "Data is required"
|
||||||
add_submission_data(nickname: "John")
|
PluginStore.set("super_mega_fun_wizard_submissions", user.id,
|
||||||
wizard = build_wizard(template, user)
|
text: 'Input into text',
|
||||||
expect(wizard.steps[0].permitted).to eq(false)
|
)
|
||||||
expect(wizard.steps[0].permitted_message).to eq(required_data_message)
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
expect(built_wizard.steps[0].permitted).to eq(false)
|
||||||
|
expect(built_wizard.steps[0].permitted_message).to eq("Data is required")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is permitted if required data is present' do
|
it 'is permitted if required data is present' do
|
||||||
template['steps'][0]['required_data'] = required_data
|
@wizard.steps[0].required_data = required_data
|
||||||
PluginStore.set('welcome_submissions', user.id, nickname: "Angus", name: "Angus")
|
PluginStore.set('super_mega_fun_wizard_submissions', user.id,
|
||||||
expect(build_wizard(template, user).steps[0].permitted).to eq(true)
|
text: "Input into text"
|
||||||
|
)
|
||||||
|
expect(
|
||||||
|
CustomWizard::Builder.new(@wizard.id, user).build.steps[0].permitted
|
||||||
|
).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns field metadata' do
|
it 'returns field metadata' do
|
||||||
expect(build_wizard(template, user).steps[0].fields[0].label).to eq("<p>Name</p>")
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
expect(build_wizard(template, user).steps[0].fields[0].type).to eq("text")
|
expect(built_wizard.steps[0].fields[0].label).to eq("<p>Name</p>")
|
||||||
|
expect(built_wizard.steps[0].fields[0].type).to eq("text")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns fields' do
|
it 'returns fields' do
|
||||||
template['steps'][0]['fields'][1] = checkbox_field
|
@wizard.steps[0].fields[1] = checkbox_field
|
||||||
expect(build_wizard(template, user).steps[0].fields.length).to eq(2)
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
expect(built_wizard.steps[0].fields.length).to eq(2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'on update' do
|
context 'on update' do
|
||||||
it 'saves submissions' do
|
it 'saves submissions' do
|
||||||
run_update(template, nil, name: 'Angus')
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
expect(get_submission_data.first['name']).to eq('Angus')
|
built_wizard.create_updater(built_wizard.steps[0].id,
|
||||||
|
step_1_field_1: 'Text input'
|
||||||
|
).update
|
||||||
|
expect(
|
||||||
|
PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
.first['step_1_field_1']
|
||||||
|
).to eq('Text input')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'validation' do
|
context 'validation' do
|
||||||
it 'applies min length' do
|
it 'applies min length' do
|
||||||
template['steps'][0]['fields'][0]['min_length'] = 10
|
@wizard.steps[0].fields[0].min_length = 10
|
||||||
updater = run_update(template, nil, name: 'short')
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
expect(updater.errors.messages[:name].first).to eq(
|
updater = built_wizard.create_updater(built_wizard.steps[0].id,
|
||||||
I18n.t('wizard.field.too_short', label: 'Name', min: 10)
|
step_1_field_1: 'Te'
|
||||||
|
).update
|
||||||
|
expect(updater.errors.messages[:text].first).to eq(
|
||||||
|
I18n.t('wizard.field.too_short', label: 'Text', min: 3)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'standardises boolean entries' do
|
it 'standardises boolean entries' do
|
||||||
template['steps'][0]['fields'][0] = checkbox_field
|
@wizard.steps[0].fields[0] = checkbox_field
|
||||||
run_update(template, nil, checkbox: 'false')
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
expect(get_submission_data.first['checkbox']).to eq(false)
|
updater = built_wizard.create_updater(built_wizard.steps[1].id,
|
||||||
|
step_2_field_5: 'false'
|
||||||
|
).update
|
||||||
|
expect(
|
||||||
|
PluginStore.get("super_mega_fun_wizard_submissions", user.id)
|
||||||
|
.first['step_2_field_5']
|
||||||
|
).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'requires required fields' do
|
it 'requires required fields' do
|
||||||
template['steps'][0]['fields'][0]['required'] = true
|
@wizard.steps[0].fields[0]['required'] = true
|
||||||
expect(run_update(template).errors.messages[:name].first).to eq(
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
I18n.t('wizard.field.required', label: 'Name')
|
updater = built_wizard.create_updater(built_wizard.steps.second.id).update
|
||||||
)
|
expect(
|
||||||
|
updater.errors.messages[:step_1_field_1].first
|
||||||
|
).to eq(I18n.t('wizard.field.required', label: 'Text'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'runs actions attached to a step' do
|
|
||||||
run_update(template, template['steps'][1]['id'], name: "Gus")
|
|
||||||
expect(user.name).to eq('Gus')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,14 +0,0 @@
|
||||||
describe CustomWizard::Mapper do
|
|
||||||
|
|
||||||
it 'interpolates user data' do
|
|
||||||
user.name = "Angus"
|
|
||||||
user.save!
|
|
||||||
|
|
||||||
expect(
|
|
||||||
CustomWizard::Builder.fill_placeholders(
|
|
||||||
"My name is u{name}",
|
|
||||||
user,
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
).to eq('My name is Angus')
|
|
||||||
end
|
|
530
spec/fixtures/wizard.json
gevendort
530
spec/fixtures/wizard.json
gevendort
|
@ -1,49 +1,525 @@
|
||||||
{
|
{
|
||||||
"id": "welcome",
|
"id": "super_mega_fun_wizard",
|
||||||
"name": "Welcome",
|
"name": "Super Mega Fun Wizard",
|
||||||
"background": "#006da3",
|
"background": "#333333",
|
||||||
"save_submissions": true,
|
"save_submissions": true,
|
||||||
"multiple_submissions": true,
|
"multiple_submissions": true,
|
||||||
"after_signup": true,
|
"after_signup": false,
|
||||||
"min_trust": 1,
|
"prompt_completion": true,
|
||||||
"theme_id": 4,
|
"theme_id": 2,
|
||||||
|
"permitted": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output_type": "group",
|
||||||
|
"output_connector": "set",
|
||||||
|
"output": [
|
||||||
|
12
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"id": "welcome",
|
"id": "step_1",
|
||||||
"title": "Welcome to Pavilion",
|
"title": "Text",
|
||||||
"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",
|
"raw_description": "Text inputs!",
|
||||||
"description": "<p>Hey there, thanks for signing up.</p>\n<p>We’re 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>",
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"id": "name",
|
"id": "step_1_field_1",
|
||||||
|
"label": "Text",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"label": "Name"
|
"min_length": "3",
|
||||||
|
"prefill": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "I am prefilled",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_2",
|
||||||
|
"label": "Textarea",
|
||||||
|
"type": "textarea",
|
||||||
|
"min_length": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_3",
|
||||||
|
"label": "Composer",
|
||||||
|
"type": "composer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_4",
|
||||||
|
"label": "I'm only text",
|
||||||
|
"description": "",
|
||||||
|
"type": "text_only"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "<p>Text inputs!</p>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2",
|
||||||
|
"title": "Values",
|
||||||
|
"raw_description": "Because I couldn't think of another name for this step :)",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "step_2_field_1",
|
||||||
|
"label": "Date",
|
||||||
|
"type": "date",
|
||||||
|
"format": "YYYY-MM-DD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_2",
|
||||||
|
"label": "Time",
|
||||||
|
"type": "time",
|
||||||
|
"format": "HH:mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_3",
|
||||||
|
"label": "Date & Time",
|
||||||
|
"type": "date_time",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_4",
|
||||||
|
"label": "Number",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_5",
|
||||||
|
"label": "Checkbox",
|
||||||
|
"type": "checkbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_7",
|
||||||
|
"label": "Upload",
|
||||||
|
"type": "upload",
|
||||||
|
"file_types": ".jpg,.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "<p>Because I couldn’t think of another name for this step <img src=\"/images/emoji/twitter/slight_smile.png?v=9\" title=\":slight_smile:\" class=\"emoji\" alt=\":slight_smile:\"></p>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3",
|
||||||
|
"title": "Combo-boxes",
|
||||||
|
"raw_description": "Unfortunately not the edible type :sushi: ",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "step_3_field_1",
|
||||||
|
"label": "Custom Dropdown",
|
||||||
|
"type": "dropdown",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "association",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "choice1",
|
||||||
|
"key_type": "text",
|
||||||
|
"value": "Choice 1",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "equal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 1,
|
||||||
|
"key": "choice2",
|
||||||
|
"key_type": "text",
|
||||||
|
"value": "Choice 2",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "association"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 2,
|
||||||
|
"key": "choice3",
|
||||||
|
"key_type": "text",
|
||||||
|
"value": "Choice 3",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "association"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_2",
|
||||||
|
"label": "Tag",
|
||||||
|
"type": "tag"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_3",
|
||||||
|
"label": "Category",
|
||||||
|
"type": "category",
|
||||||
|
"limit": 1,
|
||||||
|
"property": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_4",
|
||||||
|
"label": "Group",
|
||||||
|
"type": "group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_5",
|
||||||
|
"label": "User Selector",
|
||||||
|
"description": "",
|
||||||
|
"type": "user_selector"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "<p>Unfortunately not the edible type <img src=\"/images/emoji/twitter/sushi.png?v=9\" title=\":sushi:\" class=\"emoji\" alt=\":sushi:\"></p>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"id": "action_9",
|
||||||
|
"run_after": "step_1",
|
||||||
|
"type": "create_group",
|
||||||
|
"title": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "New Group Member",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"custom_fields": [
|
||||||
|
{
|
||||||
|
"type": "association",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "group_custom_field",
|
||||||
|
"key_type": "text",
|
||||||
|
"value": "step_3_field_1",
|
||||||
|
"value_type": "wizard_field",
|
||||||
|
"connector": "association"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_1_field_1",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"full_name": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_1_field_1",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usernames": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output_type": "user",
|
||||||
|
"output_connector": "set",
|
||||||
|
"output": [
|
||||||
|
"angus1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"owner_usernames": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output_type": "user",
|
||||||
|
"output_connector": "set",
|
||||||
|
"output": [
|
||||||
|
"angus"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"grant_trust_level": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "3",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mentionable_level": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "1",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messageable_level": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "2",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"visibility_level": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "3",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"members_visibility_level": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "99",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "about_you",
|
"id": "action_6",
|
||||||
"title": "Tell us about you",
|
"run_after": "step_1",
|
||||||
"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.",
|
"type": "add_to_group",
|
||||||
"description": "<p>We’d like to know a little more about you. Add a your name and your website below. This will update your user profile.</p>",
|
"group": [
|
||||||
"fields": [
|
|
||||||
{
|
{
|
||||||
"id": "website",
|
"type": "assignment",
|
||||||
"label": "Website",
|
"output": "action_9",
|
||||||
"type": "text"
|
"output_type": "wizard_action",
|
||||||
|
"output_connector": "set"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"actions": [
|
},
|
||||||
|
{
|
||||||
|
"id": "action_8",
|
||||||
|
"run_after": "step_1",
|
||||||
|
"type": "create_category",
|
||||||
|
"custom_fields": [
|
||||||
{
|
{
|
||||||
"id": "update_profile",
|
"type": "association",
|
||||||
"type": "update_profile",
|
"pairs": [
|
||||||
"profile_updates": [
|
|
||||||
{
|
{
|
||||||
"key": "name",
|
"index": 0,
|
||||||
"value": "name"
|
"key": "category_custom_field",
|
||||||
|
"key_type": "text",
|
||||||
|
"value": "CC Val",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "association"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_1_field_1",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"slug": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_1_field_1",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"type": "association",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "action_9",
|
||||||
|
"key_type": "wizard_action",
|
||||||
|
"value": "2",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "association"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action_5",
|
||||||
|
"run_after": "step_1",
|
||||||
|
"type": "watch_categories",
|
||||||
|
"notification_level": "tracking",
|
||||||
|
"wizard_user": true,
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "action_8",
|
||||||
|
"output_type": "wizard_action",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mute_remainder": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "true",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action_1",
|
||||||
|
"run_after": "step_2",
|
||||||
|
"type": "create_topic",
|
||||||
|
"skip_redirect": true,
|
||||||
|
"post": "step_1_field_2",
|
||||||
|
"title": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_1_field_1",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"category": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_3_field_3",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "step_3_field_2",
|
||||||
|
"output_type": "wizard_field",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"custom_fields": [
|
||||||
|
{
|
||||||
|
"type": "association",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "custom_field_1",
|
||||||
|
"key_type": "text",
|
||||||
|
"value": "title",
|
||||||
|
"value_type": "user_field",
|
||||||
|
"connector": "association"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"visible": [
|
||||||
|
{
|
||||||
|
"type": "conditional",
|
||||||
|
"output": "true",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "then",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "name",
|
||||||
|
"key_type": "user_field",
|
||||||
|
"value": "Angus",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "equal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action_4",
|
||||||
|
"run_after": "step_2",
|
||||||
|
"type": "update_profile",
|
||||||
|
"profile_updates": [
|
||||||
|
{
|
||||||
|
"type": "association",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "profile_background",
|
||||||
|
"key_type": "user_field",
|
||||||
|
"value": "step_2_field_7",
|
||||||
|
"value_type": "wizard_field",
|
||||||
|
"connector": "association"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action_2",
|
||||||
|
"run_after": "step_2",
|
||||||
|
"type": "send_message",
|
||||||
|
"post_builder": true,
|
||||||
|
"post_template": "I will interpolate some wizard fields w{step_1_field_1} w{step_1_field_2}",
|
||||||
|
"title": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "Message title",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"recipient": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output_type": "user",
|
||||||
|
"output_connector": "set",
|
||||||
|
"output": [
|
||||||
|
"angus1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action_3",
|
||||||
|
"run_after": "step_2",
|
||||||
|
"type": "open_composer",
|
||||||
|
"post_builder": true,
|
||||||
|
"post_template": "I am interpolating some user fields u{name} u{username} u{email}",
|
||||||
|
"title": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "Title of the composer topic",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"category": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "action_8",
|
||||||
|
"output_type": "wizard_action",
|
||||||
|
"output_connector": "set",
|
||||||
|
"pairs": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"key": "step_2_field_5",
|
||||||
|
"key_type": "wizard_field",
|
||||||
|
"value": "true",
|
||||||
|
"value_type": "text",
|
||||||
|
"connector": "is"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "tag1",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action_10",
|
||||||
|
"run_after": "wizard_completion",
|
||||||
|
"type": "route_to",
|
||||||
|
"url": [
|
||||||
|
{
|
||||||
|
"type": "assignment",
|
||||||
|
"output": "https://google.com",
|
||||||
|
"output_type": "text",
|
||||||
|
"output_connector": "set"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
describe CustomWizardSerializer do
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
|
||||||
fab!(:category) { Fabricate(:category) }
|
|
||||||
|
|
||||||
let!(:template) do
|
|
||||||
JSON.parse(File.open(
|
|
||||||
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
|
||||||
).read)
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:category_field) {{"id": "category","type": "category","limit": "1","label": "Category"}}
|
|
||||||
|
|
||||||
def build_wizard(t = template, u = user, build_opts = {}, params = {})
|
|
||||||
CustomWizard::Wizard.add_wizard(t)
|
|
||||||
CustomWizard::Builder.new('welcome', u).build(build_opts, params)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should return the wizard attributes' do
|
|
||||||
json = CustomWizardSerializer.new(build_wizard, scope: Guardian.new(user)).as_json
|
|
||||||
expect(json[:custom_wizard][:id]).to eq("welcome")
|
|
||||||
expect(json[:custom_wizard][:name]).to eq("Welcome")
|
|
||||||
expect(json[:custom_wizard][:background]).to eq("#006da3")
|
|
||||||
expect(json[:custom_wizard][:required]).to eq(false)
|
|
||||||
expect(json[:custom_wizard][:min_trust]).to eq(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should return the wizard user attributes" do
|
|
||||||
json = CustomWizardSerializer.new(build_wizard, scope: Guardian.new(user)).as_json
|
|
||||||
expect(json[:custom_wizard][:permitted]).to eq(true)
|
|
||||||
expect(json[:custom_wizard][:user]).to eq(BasicUserSerializer.new(user, root: false).as_json)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should not return category attributes if there are no category fields" do
|
|
||||||
json = CustomWizardSerializer.new(build_wizard, scope: Guardian.new(user)).as_json
|
|
||||||
expect(json[:custom_wizard][:categories].present?).to eq(false)
|
|
||||||
expect(json[:custom_wizard][:uncategorized_category_id].present?).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should return category attributes if there is a category selector field" do
|
|
||||||
template['steps'][0]['fields'][0] = category_field
|
|
||||||
json = CustomWizardSerializer.new(build_wizard(template), scope: Guardian.new(user)).as_json
|
|
||||||
expect(json[:custom_wizard][:categories].present?).to eq(true)
|
|
||||||
expect(json[:custom_wizard][:uncategorized_category_id].present?).to eq(true)
|
|
||||||
end
|
|
||||||
end
|
|
13
spec_offload/components/custom_wizard/mapper_spec.rb
Normale Datei
13
spec_offload/components/custom_wizard/mapper_spec.rb
Normale Datei
|
@ -0,0 +1,13 @@
|
||||||
|
describe CustomWizard::Mapper do
|
||||||
|
fab!(:user) { Fabricate(:user, name: 'Angus', username: 'angus', email: "angus@email.com") }
|
||||||
|
|
||||||
|
it 'interpolates user data' do
|
||||||
|
expect(
|
||||||
|
CustomWizard::Mapper.fill_placeholders(
|
||||||
|
"My name is u{name}",
|
||||||
|
user,
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
).to eq('My name is Angus')
|
||||||
|
end
|
||||||
|
end
|
45
spec_offload/serializers/custom_wizard/wizard_serializer_spec.rb
Normale Datei
45
spec_offload/serializers/custom_wizard/wizard_serializer_spec.rb
Normale Datei
|
@ -0,0 +1,45 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe CustomWizard::WizardSerializer do
|
||||||
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
fab!(:category) { Fabricate(:category) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
template = JSON.parse(File.open(
|
||||||
|
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
|
||||||
|
).read)
|
||||||
|
CustomWizard::Wizard.add_wizard(template)
|
||||||
|
@wizard = CustomWizard::Wizard.create('super_mega_fun_wizard', user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return the wizard attributes' do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
json = CustomWizard::WizardSerializer.new(built_wizard, scope: Guardian.new(user)).as_json
|
||||||
|
expect(json[:custom_wizard][:id]).to eq("super_mega_fun_wizard")
|
||||||
|
expect(json[:custom_wizard][:name]).to eq("Super Mega Fun Wizard")
|
||||||
|
expect(json[:custom_wizard][:background]).to eq("#333333")
|
||||||
|
expect(json[:custom_wizard][:required]).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the wizard user attributes" do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
json = CustomWizard::WizardSerializer.new(built_wizard, scope: Guardian.new(user)).as_json
|
||||||
|
expect(json[:custom_wizard][:user]).to eq(BasicUserSerializer.new(user, root: false).as_json)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not return category attributes if there are no category fields" do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
json = CustomWizard::WizardSerializer.new(built_wizard, scope: Guardian.new(user)).as_json
|
||||||
|
expect(json[:custom_wizard][:categories].present?).to eq(false)
|
||||||
|
expect(json[:custom_wizard][:uncategorized_category_id].present?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return category attributes if there is a category selector field" do
|
||||||
|
built_wizard = CustomWizard::Builder.new(@wizard.id, user).build
|
||||||
|
json = CustomWizard::WizardSerializer.new(built_wizard, scope: Guardian.new(user)).as_json
|
||||||
|
expect(json[:custom_wizard][:categories].present?).to eq(true)
|
||||||
|
expect(json[:custom_wizard][:uncategorized_category_id].present?).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
Laden …
In neuem Issue referenzieren