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

Add pro feature specs

Dieser Commit ist enthalten in:
angusmcleod 2021-09-07 20:06:13 +08:00
Ursprung 8dbb3990e4
Commit 23c4b45195
56 geänderte Dateien mit 1199 neuen und 993 gelöschten Zeilen

Datei anzeigen

@ -1,6 +1,6 @@
import { default as discourseComputed } from "discourse-common/utils/decorators"; import { default as discourseComputed } from "discourse-common/utils/decorators";
import wizardSchema from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema"; import wizardSchema from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
import { and, empty, equal, or } from "@ember/object/computed"; import { empty, equal, or } from "@ember/object/computed";
import { notificationLevels, selectKitContent } from "../lib/wizard"; import { notificationLevels, selectKitContent } from "../lib/wizard";
import { computed } from "@ember/object"; import { computed } from "@ember/object";
import UndoChanges from "../mixins/undo-changes"; import UndoChanges from "../mixins/undo-changes";

Datei anzeigen

@ -197,9 +197,9 @@ const action = {
required: ["id", "type"], required: ["id", "type"],
proTypes: [ proTypes: [
'send_message', 'send_message',
'add_to_group',
'create_category', 'create_category',
'create_group', 'create_group',
'watch_categories',
'send_to_api' 'send_to_api'
], ],
dependent: {}, dependent: {},

Datei anzeigen

@ -10,7 +10,7 @@ class CustomWizard::AdminProController < CustomWizard::AdminController
def authorize def authorize
request_id = SecureRandom.hex(32) request_id = SecureRandom.hex(32)
cookies[:user_api_request_id] = request_id cookies[:user_api_request_id] = request_id
redirect_to pro.authentication_request(current_user.id, request_id).to_s redirect_to pro.authentication_url(current_user.id, request_id).to_s
end end
def authorize_callback def authorize_callback

Datei anzeigen

@ -5,7 +5,7 @@ class CustomWizard::WizardController < ::ApplicationController
layout 'wizard' layout 'wizard'
before_action :ensure_plugin_enabled before_action :ensure_plugin_enabled
before_action :update_pro_subscription before_action :update_pro_subscription, only: [:index]
helper_method :wizard_page_title helper_method :wizard_page_title
helper_method :wizard_theme_id helper_method :wizard_theme_id
helper_method :wizard_theme_lookup helper_method :wizard_theme_lookup

Datei anzeigen

@ -1,5 +1,5 @@
{ {
"result": { "result": {
"line": 91.83 "line": 91.96
} }
} }

Datei anzeigen

@ -3,7 +3,7 @@
class CustomWizard::UpdateProSubscription < ::Jobs::Scheduled class CustomWizard::UpdateProSubscription < ::Jobs::Scheduled
every 1.hour every 1.hour
def execute(args) def execute(args={})
CustomWizard::Pro.update_subscription CustomWizard::Pro.update_subscription
end end
end end

Datei anzeigen

@ -72,6 +72,23 @@ class CustomWizard::Builder
@wizard @wizard
end end
def check_condition(template)
if template['condition'].present?
result = CustomWizard::Mapper.new(
inputs: template['condition'],
user: @wizard.user,
data: @wizard.current_submission&.fields_and_meta,
opts: {
multiple: true
}
).perform
result.any?
else
true
end
end
private private
def mapper def mapper
@ -224,23 +241,6 @@ class CustomWizard::Builder
end end
end end
def check_condition(template)
if template['condition'].present?
result = CustomWizard::Mapper.new(
inputs: template['condition'],
user: @wizard.user,
data: @wizard.current_submission&.fields_and_meta,
opts: {
multiple: true
}
).perform
result.any?
else
true
end
end
def check_if_permitted(step, step_template) def check_if_permitted(step, step_template)
step.permitted = true step.permitted = true

Datei anzeigen

@ -252,7 +252,7 @@ class CustomWizard::Mapper
end end
end end
if @pro.subscribed? && opts[:template] if opts[:template] && @pro.subscribed?
template = Liquid::Template.parse(string) template = Liquid::Template.parse(string)
string = template.render(data) string = template.render(data)
end end

Datei anzeigen

@ -54,24 +54,27 @@ class CustomWizard::Pro
return false unless data && data.is_a?(Hash) return false unless data && data.is_a?(Hash)
subscriptions = data[:subscriptions] subscriptions = data[:subscriptions]
if subscriptions.present? if subscriptions.present? && type = subscriptions.first[:price_nickname]
subscription = subscriptions.first
type = subscription[:price_nickname]
@subscription = set_subscription(type) @subscription = set_subscription(type)
return true return true
end end
end end
end end
remove_subscription destroy_subscription
false
end end
def destroy_subscription def destroy_subscription
remove_subscription if remove_subscription
@subscription = CustomWizard::ProSubscription.new(get_subscription)
!@subscription.active?
else
false
end
end end
def authentication_request(user_id, request_id) def authentication_url(user_id, request_id)
keys = @authentication.generate_keys(user_id, request_id) keys = @authentication.generate_keys(user_id, request_id)
params = { params = {
public_key: keys.public_key, public_key: keys.public_key,
@ -89,7 +92,7 @@ class CustomWizard::Pro
def authentication_response(request_id, payload) def authentication_response(request_id, payload)
data = @authentication.decrypt_payload(request_id, payload) data = @authentication.decrypt_payload(request_id, payload)
return unless data.is_a?(Hash) && data[:key] && data[:user_id] return false unless data.is_a?(Hash) && data[:key] && data[:user_id]
api_key = data[:key] api_key = data[:key]
user_id = data[:user_id] user_id = data[:user_id]
@ -104,13 +107,26 @@ class CustomWizard::Pro
end end
def destroy_authentication def destroy_authentication
remove_authentication if remove_authentication
@authentication = CustomWizard::ProAuthentication.new(get_authentication)
!@authentication.active?
else
false
end
end end
def self.subscribed? def self.subscribed?
self.new.subscribed? self.new.subscribed?
end end
def self.authorized?
self.new.authorized?
end
def self.update_subscription
self.new.update_subscription
end
def self.namespace def self.namespace
"custom_wizard_pro" "custom_wizard_pro"
end end
@ -165,5 +181,6 @@ class CustomWizard::Pro
def remove_authentication def remove_authentication
PluginStore.remove(self.class.namespace, authentication_db_key) PluginStore.remove(self.class.namespace, authentication_db_key)
get_authentication
end end
end end

Datei anzeigen

@ -30,11 +30,13 @@ class CustomWizard::ProAuthentication
def decrypt_payload(request_id, payload) def decrypt_payload(request_id, payload)
keys = get_keys(request_id) keys = get_keys(request_id)
return false unless keys.present? && keys.pem return false unless keys.present? && keys.pem
delete_keys(request_id) delete_keys(request_id)
rsa = OpenSSL::PKey::RSA.new(keys.pem) rsa = OpenSSL::PKey::RSA.new(keys.pem)
decrypted_payload = rsa.private_decrypt(Base64.decode64(payload)) decrypted_payload = rsa.private_decrypt(Base64.decode64(payload))
return false unless decrypted_payload.present? return false unless decrypted_payload.present?
begin begin
@ -49,6 +51,15 @@ class CustomWizard::ProAuthentication
data data
end end
def get_keys(request_id)
raw = PluginStore.get(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}")
OpenStruct.new(
user_id: raw && raw['user_id'],
pem: raw && raw['pem'],
nonce: raw && raw['nonce']
)
end
private private
def keys_db_key def keys_db_key
@ -67,15 +78,6 @@ class CustomWizard::ProAuthentication
) )
end end
def get_keys(request_id)
raw = PluginStore.get(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}")
OpenStruct.new(
user_id: raw && raw['user_id'],
pem: raw && raw['pem'],
nonce: raw && raw['nonce']
)
end
def delete_keys(request_id) def delete_keys(request_id)
PluginStore.remove(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}") PluginStore.remove(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}")
end end

Datei anzeigen

@ -21,8 +21,8 @@ class CustomWizard::TemplateValidator
check_required(step, :step) check_required(step, :step)
validate_pro(step, :step) validate_pro(step, :step)
if data[:fields].present? if step[:fields].present?
data[:fields].each do |field| step[:fields].each do |field|
validate_pro(field, :field) validate_pro(field, :field)
check_required(field, :field) check_required(field, :field)
end end
@ -66,9 +66,9 @@ class CustomWizard::TemplateValidator
action: { action: {
type: %w[ type: %w[
send_message send_message
add_to_group
create_category create_category
create_group create_group
watch_categories
send_to_api send_to_api
] ]
} }
@ -87,11 +87,13 @@ class CustomWizard::TemplateValidator
def validate_pro(object, type) def validate_pro(object, type)
self.class.pro[type].each do |property, pro_type| self.class.pro[type].each do |property, pro_type|
is_pro = (pro_type === 'present' && object[property].present?) || is_pro = object[property.to_s].present? && (
(pro_type === 'conditional' && object[property].is_a?(Hash)) || pro_type === 'present' ||
(pro_type.is_a?(Array) && pro_type.includes?(object[property])) (pro_type === 'conditional' && object[property.to_s].is_a?(Hash)) ||
(pro_type.is_a?(Array) && pro_type.include?(object[property.to_s]))
)
if is_pro && @pro.subscribed? if is_pro && !@pro.subscribed?
errors.add :base, I18n.t("wizard.validation.pro", type: type.to_s, property: property) errors.add :base, I18n.t("wizard.validation.pro", type: type.to_s, property: property)
end end
end end

Datei anzeigen

@ -308,10 +308,10 @@ class CustomWizard::Wizard
end end
end end
def self.list(user, template_opts: {}, not_completed: false) def self.list(user, template_opts = {}, not_completed = false)
return [] unless user return [] unless user
CustomWizard::Template.list(template_opts).reduce([]) do |result, template| CustomWizard::Template.list(**template_opts).reduce([]) do |result, template|
wizard = new(template, user) wizard = new(template, user)
result.push(wizard) if wizard.can_access? && ( result.push(wizard) if wizard.can_access? && (
!not_completed || !wizard.completed? !not_completed || !wizard.completed?
@ -323,7 +323,7 @@ class CustomWizard::Wizard
def self.after_signup(user) def self.after_signup(user)
wizards = list( wizards = list(
user, user,
template_opts: { {
setting: 'after_signup', setting: 'after_signup',
order: "(value::json ->> 'permitted') IS NOT NULL DESC" order: "(value::json ->> 'permitted') IS NOT NULL DESC"
} }
@ -334,11 +334,11 @@ class CustomWizard::Wizard
def self.prompt_completion(user) def self.prompt_completion(user)
wizards = list( wizards = list(
user, user,
template_opts: { {
setting: 'prompt_completion', setting: 'prompt_completion',
order: "(value::json ->> 'permitted') IS NOT NULL DESC" order: "(value::json ->> 'permitted') IS NOT NULL DESC"
}, },
not_completed: true true
) )
if wizards.any? if wizards.any?
wizards.map do |w| wizards.map do |w|

Datei anzeigen

@ -6,26 +6,22 @@ describe CustomWizard::Action do
fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') } fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') }
fab!(:group) { Fabricate(:group) } fab!(:group) { Fabricate(:group) }
let(:wizard_template) { let(:wizard_template) { get_wizard_fixture("wizard") }
JSON.parse( let(:open_composer) { get_wizard_fixture("actions/open_composer") }
File.open( let(:create_category) { get_wizard_fixture("actions/create_category") }
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" let(:create_group) { get_wizard_fixture("actions/create_group") }
).read let(:add_to_group) { get_wizard_fixture("actions/add_to_group") }
) let(:send_message) { get_wizard_fixture("actions/send_message") }
} let(:send_message_multi) { get_wizard_fixture("actions/send_message_multi") }
let(:open_composer) { def update_template(template)
JSON.parse( CustomWizard::Template.save(template, skip_jobs: true)
File.open( @template = CustomWizard::Template.find('super_mega_fun_wizard')
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/actions/open_composer.json" end
).read
)
}
before do before do
Group.refresh_automatic_group!(:trust_level_2) Group.refresh_automatic_group!(:trust_level_2)
CustomWizard::Template.save(wizard_template, skip_jobs: true) update_template(wizard_template)
@template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
context 'creating a topic' do context 'creating a topic' do
@ -110,54 +106,6 @@ describe CustomWizard::Action do
end end
end end
context 'sending a message' do
it 'works' 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 'allows using multiple PM targets' do
User.create(username: 'angus1', email: "angus1@email.com")
User.create(username: 'faiz', email: "faiz@email.com")
Group.create(name: "cool_group")
Group.create(name: 'cool_group_1')
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: "Multiple Recipients 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.all_allowed_users.map(&:username)).to include('angus1', 'faiz')
expect(topic.first.allowed_groups.map(&:name)).to include('cool_group', 'cool_group_1')
expect(post.exists?).to eq(true)
end
end
it 'updates a profile' do it 'updates a profile' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
upload = Upload.create!( upload = Upload.create!(
@ -182,10 +130,8 @@ describe CustomWizard::Action do
updater = wizard.create_updater(wizard.steps[1].id, {}) updater = wizard.create_updater(wizard.steps[1].id, {})
updater.update updater.update
category = Category.find_by(id: wizard.current_submission.fields['action_8'])
expect(updater.result[:redirect_on_next]).to eq( expect(updater.result[:redirect_on_next]).to eq(
"/new-topic?title=Title%20of%20the%20composer%20topic&body=I%20am%20interpolating%20some%20user%20fields%20Angus%20angus%20angus%40email.com&category_id=#{category.id}&tags=tag1" "/new-topic?title=Title%20of%20the%20composer%20topic&body=I%20am%20interpolating%20some%20user%20fields%20Angus%20angus%20angus%40email.com&tags=tag1"
) )
end end
@ -210,35 +156,11 @@ describe CustomWizard::Action do
end end
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.fields['action_8']).exists?).to eq(true)
end
it 'creates a group' do
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
expect(Group.where(name: wizard.current_submission.fields['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
updater = wizard.create_updater(step_id, step_1_field_1: "Text input").update
group = Group.find_by(name: wizard.current_submission.fields['action_9'])
expect(group.users.first.username).to eq('angus')
end
it 'watches categories' do it 'watches categories' do
wizard = CustomWizard::Builder.new(@template[:id], user).build wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
wizard.create_updater(wizard.steps[1].id, {}).update wizard.create_updater(wizard.steps[1].id, {}).update
expect(CategoryUser.where(
category_id: wizard.current_submission.fields['action_8'],
user_id: user.id
).first.notification_level).to eq(2)
expect(CategoryUser.where( expect(CategoryUser.where(
category_id: category.id, category_id: category.id,
user_id: user.id user_id: user.id
@ -251,4 +173,97 @@ describe CustomWizard::Action do
updater.update updater.update
expect(updater.result[:redirect_on_next]).to eq("https://google.com") expect(updater.result[:redirect_on_next]).to eq("https://google.com")
end end
context "pro actions" do
before do
enable_pro
end
it '#send_message' do
wizard_template['actions'] << send_message
update_template(wizard_template)
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 '#send_message allows using multiple targets' do
wizard_template['actions'] << send_message_multi
update_template(wizard_template)
User.create(username: 'angus1', email: "angus1@email.com")
User.create(username: 'faiz', email: "faiz@email.com")
Group.create(name: "cool_group")
Group.create(name: 'cool_group_1')
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: "Multiple Recipients 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.all_allowed_users.map(&:username)).to include('angus1', 'faiz')
expect(topic.first.allowed_groups.map(&:name)).to include('cool_group', 'cool_group_1')
expect(post.exists?).to eq(true)
end
it '#create_category' do
wizard_template['actions'] << create_category
update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
wizard.create_updater(wizard.steps[1].id, {}).update
expect(Category.where(id: wizard.current_submission.fields['action_8']).exists?).to eq(true)
end
it '#create_group' do
wizard_template['actions'] << create_group
update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
expect(Group.where(name: wizard.current_submission.fields['action_9']).exists?).to eq(true)
end
it '#add_to_group' do
wizard_template['actions'] << create_group
wizard_template['actions'] << add_to_group
update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build
step_id = wizard.steps[0].id
updater = wizard.create_updater(step_id, step_1_field_1: "Text input").update
group = Group.find_by(name: wizard.current_submission.fields['action_9'])
expect(group.users.first.username).to eq('angus')
end
end
end end

Datei anzeigen

@ -15,45 +15,15 @@ describe CustomWizard::Builder do
fab!(:category2) { Fabricate(:category, name: 'cat2') } fab!(:category2) { Fabricate(:category, name: 'cat2') }
fab!(:group) { Fabricate(:group) } fab!(:group) { Fabricate(:group) }
let(:required_data_json) { let(:wizard_template) { get_wizard_fixture("wizard") }
JSON.parse( let(:required_data_json) { get_wizard_fixture("step/required_data") }
File.open( let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/required_data.json" let(:permitted_param_json) { get_wizard_fixture("step/permitted_params") }
).read let(:user_condition_json) { get_wizard_fixture("condition/user_condition") }
)
}
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
)
}
let(:user_condition_json) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/user_condition.json"
).read
)
}
before do before do
Group.refresh_automatic_group!(:trust_level_3) Group.refresh_automatic_group!(:trust_level_3)
CustomWizard::Template.save( CustomWizard::Template.save(wizard_template, skip_jobs: true)
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read),
skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end
@ -283,6 +253,7 @@ describe CustomWizard::Builder do
context "with condition" do context "with condition" do
before do before do
enable_pro
@template[:steps][0][:condition] = user_condition_json['condition'] @template[:steps][0][:condition] = user_condition_json['condition']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
@ -321,6 +292,7 @@ describe CustomWizard::Builder do
context "with condition" do context "with condition" do
before do before do
enable_pro
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition'] @template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end

Datei anzeigen

@ -3,12 +3,8 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::CustomField do describe CustomWizard::CustomField do
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
let(:custom_field_json) { let(:custom_field_pro_json) { get_wizard_fixture("custom_field/pro_custom_fields") }
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read)
}
before do before do
CustomWizard::CustomField.invalidate_cache CustomWizard::CustomField.invalidate_cache
@ -104,8 +100,8 @@ describe CustomWizard::CustomField do
it "does not save with an unsupported serializer" do it "does not save with an unsupported serializer" do
invalid_field_json = custom_field_json['custom_fields'].first invalid_field_json = custom_field_json['custom_fields'].first
invalid_field_json['klass'] = 'category' invalid_field_json['klass'] = 'post'
invalid_field_json['serializers'] = ['category', 'site_category'] invalid_field_json['serializers'] = ['post', 'post_revision']
custom_field = CustomWizard::CustomField.new(nil, invalid_field_json) custom_field = CustomWizard::CustomField.new(nil, invalid_field_json)
@ -113,8 +109,8 @@ describe CustomWizard::CustomField do
expect(custom_field.valid?).to eq(false) expect(custom_field.valid?).to eq(false)
expect(custom_field.errors.full_messages.first).to eq( expect(custom_field.errors.full_messages.first).to eq(
I18n.t("wizard.custom_field.error.unsupported_serializers", I18n.t("wizard.custom_field.error.unsupported_serializers",
class: "category", class: "post",
serializers: "category, site_category" serializers: "post_revision"
) )
) )
expect( expect(
@ -196,6 +192,50 @@ describe CustomWizard::CustomField do
).exists? ).exists?
).to eq(false) ).to eq(false)
end end
it "does not save pro field types without a pro subscription" do
pro_field_json = custom_field_pro_json['custom_fields'].first
custom_field = CustomWizard::CustomField.new(nil, pro_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.pro_type", type: "json")
)
end
it "does not save pro field classes without a pro subscription" do
pro_field_json = custom_field_pro_json['custom_fields'].second
custom_field = CustomWizard::CustomField.new(nil, pro_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.pro_type", type: "category")
)
end
context "with a pro subscription" do
before do
enable_pro
end
it "saves pro field types" do
pro_field_json = custom_field_pro_json['custom_fields'].first
custom_field = CustomWizard::CustomField.new(nil, pro_field_json)
expect(custom_field.save).to eq(true)
expect(custom_field.valid?).to eq(true)
end
it "saves pro field classes" do
pro_field_json = custom_field_pro_json['custom_fields'].second
custom_field = CustomWizard::CustomField.new(nil, pro_field_json)
expect(custom_field.save).to eq(true)
expect(custom_field.valid?).to eq(true)
end
end
end end
context "lists" do context "lists" do
@ -205,15 +245,15 @@ describe CustomWizard::CustomField do
end end
end end
it "lists saved custom field records" do it "saved custom field records" do
expect(CustomWizard::CustomField.list.length).to eq(4) expect(CustomWizard::CustomField.list.length).to eq(2)
end end
it "lists saved custom field records by attribute value" do it "saved custom field records by attribute value" do
expect(CustomWizard::CustomField.list_by(:klass, 'topic').length).to eq(1) expect(CustomWizard::CustomField.list_by(:klass, 'topic').length).to eq(1)
end end
it "lists saved custom field records by optional values" do it "saved custom field records by optional values" do
field_json = custom_field_json['custom_fields'].first field_json = custom_field_json['custom_fields'].first
field_json['serializers'] = nil field_json['serializers'] = nil
@ -221,12 +261,12 @@ describe CustomWizard::CustomField do
expect(CustomWizard::CustomField.list_by(:serializers, ['post']).length).to eq(0) expect(CustomWizard::CustomField.list_by(:serializers, ['post']).length).to eq(0)
end end
it "lists custom field records added by other plugins " do it "custom field records added by other plugins " do
expect(CustomWizard::CustomField.external_list.length).to eq(11) expect(CustomWizard::CustomField.external_list.length).to be > 10
end end
it "lists all custom field records" do it "all custom field records" do
expect(CustomWizard::CustomField.full_list.length).to eq(15) expect(CustomWizard::CustomField.full_list.length).to be > 12
end end
end end

Datei anzeigen

@ -2,11 +2,7 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Field do describe CustomWizard::Field do
let(:field_hash) do let(:field_hash) { get_wizard_fixture("field/field") }
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/field.json"
).read).with_indifferent_access
end
before do before do
CustomWizard::Field.register( CustomWizard::Field.register(

Datei anzeigen

@ -31,16 +31,8 @@ describe CustomWizard::Mapper do
] ]
) )
} }
let(:inputs) { let(:inputs) { get_wizard_fixture("mapper/inputs") }
JSON.parse(File.open( let(:data) { get_wizard_fixture("mapper/data") }
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/mapper/inputs.json"
).read)
}
let(:data) {
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/mapper/data.json"
).read)
}
let(:template_params) { let(:template_params) {
{ {
"step_1_field_1" => "Hello" "step_1_field_1" => "Hello"
@ -352,7 +344,7 @@ describe CustomWizard::Mapper do
expect(result).to eq(template_params["step_1_field_1"]) expect(result).to eq(template_params["step_1_field_1"])
end end
it "treats replaced values as string literals" do it "requires a pro subscription" do
template = '{{ "w{step_1_field_1}" | size }}' template = '{{ "w{step_1_field_1}" | size }}'
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result = mapper.interpolate(
@ -362,60 +354,17 @@ describe CustomWizard::Mapper do
wizard: true, wizard: true,
value: true value: true
) )
expect(result).to eq(template_params["step_1_field_1"].size.to_s) expect(result).to eq("{{ \"#{template_params["step_1_field_1"]}\" | size }}")
end end
it "allows the wizard values to be used inside conditionals" do context "with a pro subscription" do
template = <<-LIQUID before do
{%- if "w{step_1_field_1}" contains "ello" -%} enable_pro
Correct end
{%- else -%}
Incorrect
{%-endif-%}
LIQUID
mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate(
template.dup,
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq("Correct")
end
it "can access data passed to render method as variable" do it "treats replaced values as string literals" do
template = "{{step_1_field_1.size}}" template = '{{ "w{step_1_field_1}" | size }}'
mapper = create_template_mapper(template_params, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate(
template.dup,
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params["step_1_field_1"].size.to_s)
end
it "doesn't parse the template when template param is false" do
template = <<-LIQUID.strip
{{ "w{step_1_field_1}" | size}}
LIQUID
mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate(
template.dup,
template: false,
)
expect(result).to eq(template)
end
context "custom filter: 'first_non_empty'" do
it "gives first non empty element from list" do
template = <<-LIQUID.strip
{%- assign entry = "" | first_non_empty: step_1_field_1, step_1_field_2, step_1_field_3 -%}
{{ entry }}
LIQUID
mapper = create_template_mapper(template_params_non_empty, user1)
result = mapper.interpolate( result = mapper.interpolate(
template.dup, template.dup,
template: true, template: true,
@ -423,15 +372,18 @@ describe CustomWizard::Mapper do
wizard: true, wizard: true,
value: true value: true
) )
expect(result).to eq(template_params_non_empty["step_1_field_3"]) expect(result).to eq(template_params["step_1_field_1"].size.to_s)
end end
it "gives first non empty element from list when multiple non empty values present" do it "allows the wizard values to be used inside conditionals" do
template = <<-LIQUID.strip template = <<-LIQUID
{%- assign entry = "" | first_non_empty: step_1_field_1, step_1_field_2, step_1_field_3 -%} {%- if "w{step_1_field_1}" contains "ello" -%}
{{ entry }} Correct
{%- else -%}
Incorrect
{%-endif-%}
LIQUID LIQUID
mapper = create_template_mapper(template_params_multiple_non_empty, user1) mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate( result = mapper.interpolate(
template.dup, template.dup,
template: true, template: true,
@ -439,25 +391,84 @@ describe CustomWizard::Mapper do
wizard: true, wizard: true,
value: true value: true
) )
expect(result).to eq(template_params_multiple_non_empty["step_1_field_2"]) expect(result).to eq("Correct")
end end
it "gives empty if all elements are empty" do it "can access data passed to render method as variable" do
template = "{{step_1_field_1.size}}"
mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate(
template.dup,
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params["step_1_field_1"].size.to_s)
end
it "doesn't parse the template when template param is false" do
template = <<-LIQUID.strip template = <<-LIQUID.strip
{%- assign entry = "" | first_non_empty: step_1_field_1, step_1_field_2, step_1_field_3 -%} {{ "w{step_1_field_1}" | size}}
{%- if entry -%} LIQUID
mapper = create_template_mapper(template_params, user1)
result = mapper.interpolate(
template.dup,
template: false,
)
expect(result).to eq(template)
end
context "custom filter: 'first_non_empty'" do
it "gives first non empty element from list" do
template = <<-LIQUID.strip
{%- assign entry = "" | first_non_empty: step_1_field_1, step_1_field_2, step_1_field_3 -%}
{{ entry }} {{ entry }}
{%- endif -%} LIQUID
LIQUID mapper = create_template_mapper(template_params_non_empty, user1)
mapper = create_template_mapper(template_params_empty, user1) result = mapper.interpolate(
result = mapper.interpolate( template.dup,
template.dup, template: true,
template: true, user: true,
user: true, wizard: true,
wizard: true, value: true
value: true )
) expect(result).to eq(template_params_non_empty["step_1_field_3"])
expect(result).to eq("") end
it "gives first non empty element from list when multiple non empty values present" do
template = <<-LIQUID.strip
{%- assign entry = "" | first_non_empty: step_1_field_1, step_1_field_2, step_1_field_3 -%}
{{ entry }}
LIQUID
mapper = create_template_mapper(template_params_multiple_non_empty, user1)
result = mapper.interpolate(
template.dup,
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq(template_params_multiple_non_empty["step_1_field_2"])
end
it "gives empty if all elements are empty" do
template = <<-LIQUID.strip
{%- assign entry = "" | first_non_empty: step_1_field_1, step_1_field_2, step_1_field_3 -%}
{%- if entry -%}
{{ entry }}
{%- endif -%}
LIQUID
mapper = create_template_mapper(template_params_empty, user1)
result = mapper.interpolate(
template.dup,
template: true,
user: true,
wizard: true,
value: true
)
expect(result).to eq("")
end
end end
end end
end end

Datei anzeigen

@ -0,0 +1,125 @@
# frozen_string_literal: true
require_relative '../../plugin_helper'
describe CustomWizard::Pro do
fab!(:user) { Fabricate(:user) }
it "initializes pro authentication and subscription" do
pro = described_class.new
expect(pro.authentication.class).to eq(CustomWizard::ProAuthentication)
expect(pro.subscription.class).to eq(CustomWizard::ProSubscription)
end
it "returns authorized and subscribed states" do
pro = described_class.new
expect(pro.authorized?).to eq(false)
expect(pro.subscribed?).to eq(false)
end
context "subscription" do
before do
@pro = described_class.new
end
it "updates valid subscriptions" do
stub_subscription_request(200, valid_subscription)
expect(@pro.update_subscription).to eq(true)
expect(@pro.subscribed?).to eq(true)
end
it "handles invalid subscriptions" do
stub_subscription_request(200, invalid_subscription)
expect(@pro.update_subscription).to eq(false)
expect(@pro.subscribed?).to eq(false)
end
it "handles subscription http errors" do
stub_subscription_request(404, {})
expect(@pro.update_subscription).to eq(false)
expect(@pro.subscribed?).to eq(false)
end
it "destroys subscriptions" do
stub_subscription_request(200, valid_subscription)
expect(@pro.update_subscription).to eq(true)
expect(@pro.destroy_subscription).to eq(true)
expect(@pro.subscribed?).to eq(false)
end
it "has class aliases" do
authenticate_pro
stub_subscription_request(200, valid_subscription)
expect(described_class.update_subscription).to eq(true)
expect(described_class.subscribed?).to eq(true)
end
end
context "authentication" do
before do
@pro = described_class.new
user.update!(admin: true)
end
it "generates a valid authentication request url" do
request_id = SecureRandom.hex(32)
uri = URI(@pro.authentication_url(user.id, request_id))
expect(uri.host).to eq(@pro.server)
parsed_query = Rack::Utils.parse_query uri.query
expect(parsed_query['public_key'].present?).to eq(true)
expect(parsed_query['nonce'].present?).to eq(true)
expect(parsed_query['client_id'].present?).to eq(true)
expect(parsed_query['auth_redirect'].present?).to eq(true)
expect(parsed_query['application_name']).to eq(SiteSetting.title)
expect(parsed_query['scopes']).to eq(@pro.scope)
end
def generate_payload(request_id, user_id)
uri = URI(@pro.authentication_url(user_id, request_id))
keys = @pro.authentication.get_keys(request_id)
raw_payload = {
key: "12345",
nonce: keys.nonce,
push: false,
api: UserApiKeysController::AUTH_API_VERSION
}.to_json
public_key = OpenSSL::PKey::RSA.new(keys.pem)
Base64.encode64(public_key.public_encrypt(raw_payload))
end
it "handles authentication response if request and response is valid" do
request_id = SecureRandom.hex(32)
payload = generate_payload(request_id, user.id)
expect(@pro.authentication_response(request_id, payload)).to eq(true)
expect(@pro.authorized?).to eq(true)
end
it "discards authentication response if user who made request as not an admin" do
user.update!(admin: false)
request_id = SecureRandom.hex(32)
payload = generate_payload(request_id, user.id)
expect(@pro.authentication_response(request_id, payload)).to eq(false)
expect(@pro.authorized?).to eq(false)
end
it "discards authentication response if request_id is invalid" do
payload = generate_payload(SecureRandom.hex(32), user.id)
expect(@pro.authentication_response(SecureRandom.hex(32), payload)).to eq(false)
expect(@pro.authorized?).to eq(false)
end
it "destroys authentication" do
request_id = SecureRandom.hex(32)
payload = generate_payload(request_id, user.id)
@pro.authentication_response(request_id, payload)
expect(@pro.destroy_authentication).to eq(true)
expect(@pro.authorized?).to eq(false)
end
end
end

Datei anzeigen

@ -2,21 +2,8 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::Step do describe CustomWizard::Step do
let(:step_hash) do let(:step_hash) { get_wizard_fixture("step/step") }
JSON.parse( let(:field_hash) { get_wizard_fixture("field/field") }
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/step.json"
).read
).with_indifferent_access
end
let(:field_hash) do
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/field.json"
).read
).with_indifferent_access
end
before do before do
@step = CustomWizard::Step.new(step_hash[:id]) @step = CustomWizard::Step.new(step_hash[:id])

Datei anzeigen

@ -4,12 +4,7 @@ require_relative '../../plugin_helper'
describe CustomWizard::Submission do describe CustomWizard::Submission do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
let(:template_json) { get_wizard_fixture("wizard") }
let(:template_json) {
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
}
before do before do
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)

Datei anzeigen

@ -3,17 +3,8 @@ require_relative '../../plugin_helper'
describe CustomWizard::Template do describe CustomWizard::Template do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template_json) { get_wizard_fixture("wizard") }
let(:template_json) { let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
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 before do
CustomWizard::Template.save(template_json, skip_jobs: true) CustomWizard::Template.save(template_json, skip_jobs: true)

Datei anzeigen

@ -3,12 +3,9 @@ require_relative '../../plugin_helper'
describe CustomWizard::TemplateValidator do describe CustomWizard::TemplateValidator do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template) { get_wizard_fixture("wizard") }
let(:template) { let(:create_category) { get_wizard_fixture("actions/create_category") }
JSON.parse(File.open( let(:user_condition) { get_wizard_fixture("condition/user_condition") }
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read).with_indifferent_access
}
it "validates valid templates" do it "validates valid templates" do
expect( expect(
@ -45,4 +42,52 @@ describe CustomWizard::TemplateValidator do
CustomWizard::TemplateValidator.new(template).perform CustomWizard::TemplateValidator.new(template).perform
).to eq(false) ).to eq(false)
end end
it "invalidates pro step attributes without a pro subscription" do
template[:steps][0][:condition] = user_condition['condition']
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end
it "invalidates pro field attributes without a pro subscription" do
template[:steps][0][:fields][0][:condition] = user_condition['condition']
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end
it "invalidates pro actions without a pro subscription" do
template[:actions] << create_category
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
end
context "with pro subscription" do
before do
enable_pro
end
it "validates pro step attributes" do
template[:steps][0][:condition] = user_condition['condition']
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end
it "validates pro field attributes" do
template[:steps][0][:fields][0][:condition] = user_condition['condition']
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end
it "validates pro actions" do
template[:actions] << create_category
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end
end
end end

Datei anzeigen

@ -3,12 +3,7 @@ require_relative '../../plugin_helper'
describe CustomWizard::UpdateValidator do describe CustomWizard::UpdateValidator do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template) { get_wizard_fixture("wizard") }
let(:template) {
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read).with_indifferent_access
}
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)

Datei anzeigen

@ -6,22 +6,8 @@ describe CustomWizard::Wizard do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:trusted_user) { Fabricate(:user, trust_level: TrustLevel[3]) } fab!(:trusted_user) { Fabricate(:user, trust_level: TrustLevel[3]) }
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:template_json) { get_wizard_fixture("wizard") }
let(:template_json) { let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
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 before do
Group.refresh_automatic_group!(:trust_level_3) Group.refresh_automatic_group!(:trust_level_3)

Datei anzeigen

@ -9,11 +9,8 @@ describe "custom field extensions" do
fab!(:group) { Fabricate(:group) } fab!(:group) { Fabricate(:group) }
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:custom_field_json) { let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
JSON.parse(File.open( let(:pro_custom_field_json) { get_wizard_fixture("custom_field/pro_custom_fields") }
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read)
}
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
@ -75,43 +72,54 @@ describe "custom field extensions" do
end end
end end
context "category" do context "pro custom fields" do
it "registers category custom fields" do before do
category enable_pro
expect(Category.get_custom_field_type("category_field_1")).to eq(:json)
pro_custom_field_json['custom_fields'].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save
end
end end
it "adds category custom fields to the basic category serializer" do context "category" do
category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json it "registers" do
category.save_custom_fields(true) category
expect(Category.get_custom_field_type("category_field_1")).to eq(:json)
end
serializer = BasicCategorySerializer.new( it "adds custom fields to the basic category serializer" do
category, category.custom_fields["category_field_1"] = { a: 1, b: 2 }.to_json
scope: Guardian.new(user), category.save_custom_fields(true)
root: false
).as_json
expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json) serializer = BasicCategorySerializer.new(
end category,
end scope: Guardian.new(user),
root: false
).as_json
context "group" do expect(serializer[:category_field_1]).to eq({ a: 1, b: 2 }.to_json)
it "registers group custom fields" do end
group
expect(Group.get_custom_field_type("group_field_1")).to eq(:string)
end end
it "adds group custom fields to the basic group serializer" do context "group" do
group.custom_fields["group_field_1"] = "Hello" it "registers" do
group.save_custom_fields(true) group
expect(Group.get_custom_field_type("group_field_1")).to eq(:string)
end
serializer = BasicGroupSerializer.new( it "adds custom fields to the basic group serializer" do
group, group.custom_fields["group_field_1"] = "Hello"
scope: Guardian.new(user), group.save_custom_fields(true)
root: false
).as_json
expect(serializer[:group_field_1]).to eq("Hello") serializer = BasicGroupSerializer.new(
group,
scope: Guardian.new(user),
root: false
).as_json
expect(serializer[:group_field_1]).to eq("Hello")
end
end end
end end
end end

Datei anzeigen

@ -4,18 +4,8 @@ require_relative '../plugin_helper'
describe ExtraLocalesControllerCustomWizard, type: :request do describe ExtraLocalesControllerCustomWizard, type: :request do
let(:new_user) { Fabricate(:user, trust_level: TrustLevel[0]) } let(:new_user) { Fabricate(:user, trust_level: TrustLevel[0]) }
let(:staff_user) { Fabricate(:moderator) } let(:staff_user) { Fabricate(:moderator) }
let(:template) { get_wizard_fixture("wizard") }
let(:template) { let(:permitted) { get_wizard_fixture("wizard/permitted") }
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 before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)

Datei anzeigen

@ -4,12 +4,7 @@ require_relative '../plugin_helper'
describe InvitesControllerCustomWizard, type: :request do describe InvitesControllerCustomWizard, type: :request do
fab!(:topic) { Fabricate(:topic) } fab!(:topic) { Fabricate(:topic) }
let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) } let(:invite) { Invite.generate(topic.user, email: "angus@mcleod.org", topic: topic) }
let(:template) { get_wizard_fixture("wizard") }
let(:template) do
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
end
before do before do
@controller = InvitesController.new @controller = InvitesController.new

Datei anzeigen

@ -2,11 +2,7 @@
require_relative '../plugin_helper' require_relative '../plugin_helper'
describe CustomWizardUsersController, type: :request do describe CustomWizardUsersController, type: :request do
let(:template) do let(:template) { get_wizard_fixture("wizard") }
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
end
before do before do
@controller = UsersController.new @controller = UsersController.new

13
spec/fixtures/actions/add_to_group.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,13 @@
{
"id": "action_6",
"run_after": "step_1",
"type": "add_to_group",
"group": [
{
"type": "assignment",
"output": "action_9",
"output_type": "wizard_action",
"output_connector": "set"
}
]
}

51
spec/fixtures/actions/create_category.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,51 @@
{
"id": "action_8",
"run_after": "step_1",
"type": "create_category",
"custom_fields": [
{
"type": "association",
"pairs": [
{
"index": 0,
"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"
}
]
}
]
}

104
spec/fixtures/actions/create_group.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,104 @@
{
"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"
}
]
}

25
spec/fixtures/actions/send_message.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,25 @@
{
"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"
]
}
]
}

Datei anzeigen

@ -0,0 +1,28 @@
{
"id": "action_11",
"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": "Multiple Recipients title",
"output_type": "text",
"output_connector": "set"
}
],
"recipient": [
{
"type": "assignment",
"output_type": "user",
"output_connector": "set",
"output": [
"angus1",
"faiz",
"cool_group",
"cool_group_1"
]
}
]
}

Datei anzeigen

@ -16,22 +16,6 @@
"serializers": [ "serializers": [
"post" "post"
] ]
},
{
"klass": "category",
"name": "category_field_1",
"type": "json",
"serializers": [
"basic_category"
]
},
{
"klass": "group",
"name": "group_field_1",
"type": "string",
"serializers": [
"basic_group"
]
} }
] ]
} }

Datei anzeigen

@ -0,0 +1,28 @@
{
"custom_fields": [
{
"klass": "topic",
"name": "topic_field_2",
"type": "json",
"serializers": [
"topic_view"
]
},
{
"klass": "category",
"name": "category_field_1",
"type": "json",
"serializers": [
"basic_category"
]
},
{
"klass": "group",
"name": "group_field_1",
"type": "string",
"serializers": [
"basic_group"
]
}
]
}

Datei anzeigen

@ -163,197 +163,6 @@
} }
], ],
"actions": [ "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": "action_6",
"run_after": "step_1",
"type": "add_to_group",
"group": [
{
"type": "assignment",
"output": "action_9",
"output_type": "wizard_action",
"output_connector": "set"
}
]
},
{
"id": "action_8",
"run_after": "step_1",
"type": "create_category",
"custom_fields": [
{
"type": "association",
"pairs": [
{
"index": 0,
"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", "id": "action_1",
"run_after": "step_3", "run_after": "step_3",
@ -442,6 +251,29 @@
} }
] ]
}, },
{
"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_4", "id": "action_4",
"run_after": "step_2", "run_after": "step_2",
@ -462,59 +294,6 @@
} }
] ]
}, },
{
"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_11",
"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": "Multiple Recipients title",
"output_type": "text",
"output_connector": "set"
}
],
"recipient": [
{
"type": "assignment",
"output_type": "user",
"output_connector": "set",
"output": [
"angus1",
"faiz",
"cool_group",
"cool_group_1"
]
}
]
},
{ {
"id": "action_3", "id": "action_3",
"run_after": "step_2", "run_after": "step_2",
@ -529,24 +308,6 @@
"output_connector": "set" "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": [ "tags": [
{ {
"type": "assignment", "type": "assignment",

Datei anzeigen

@ -7,11 +7,7 @@ describe Jobs::SetAfterTimeWizard do
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
fab!(:user3) { Fabricate(:user) } fab!(:user3) { Fabricate(:user) }
let(:template) { let(:template) { get_wizard_fixture("wizard") }
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read).with_indifferent_access
}
it "sets wizard redirect for all users " do it "sets wizard redirect for all users " do
after_time_template = template.dup after_time_template = template.dup

Datei anzeigen

@ -0,0 +1,11 @@
# frozen_string_literal: true
require_relative '../plugin_helper'
describe CustomWizard::UpdateProSubscription do
it "updates the pro subscription" do
stub_subscription_request(200, valid_subscription)
described_class.new.execute
expect(CustomWizard::Pro.subscribed?).to eq(true)
end
end

Datei anzeigen

@ -15,3 +15,44 @@ require 'oj'
Oj.default_options = Oj.default_options.merge(cache_str: -1) Oj.default_options = Oj.default_options.merge(cache_str: -1)
require 'rails_helper' require 'rails_helper'
def get_wizard_fixture(path)
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/#{path}.json"
).read
).with_indifferent_access
end
def authenticate_pro
CustomWizard::ProAuthentication.any_instance.stubs(:active?).returns(true)
end
def enable_pro
CustomWizard::Pro.any_instance.stubs(:subscribed?).returns(true)
end
def disable_pro
CustomWizard::Pro.any_instance.stubs(:subscribed?).returns(false)
end
def valid_subscription
{
product_id: "prod_CBTNpi3fqWWkq0",
price_id: "price_id",
price_nickname: "business"
}
end
def invalid_subscription
{
product_id: "prod_CBTNpi3fqWWkq0",
price_id: "price_id"
}
end
def stub_subscription_request(status, subscription)
authenticate_pro
pro = CustomWizard::Pro.new
stub_request(:get, "https://#{pro.server}/subscription-server/user-subscriptions/#{pro.subscription_type}/#{pro.client_name}").to_return(status: status, body: { subscriptions: [subscription] }.to_json)
end

Datei anzeigen

@ -3,12 +3,7 @@ require_relative '../../../plugin_helper'
describe CustomWizard::AdminCustomFieldsController do describe CustomWizard::AdminCustomFieldsController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
let(:custom_field_json) {
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json"
).read)
}
before do before do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|
@ -19,7 +14,7 @@ describe CustomWizard::AdminCustomFieldsController do
it "returns the full list of custom fields" do it "returns the full list of custom fields" do
get "/admin/wizards/custom-fields.json" get "/admin/wizards/custom-fields.json"
expect(response.parsed_body.length).to eq(15) expect(response.parsed_body["custom_fields"].length).to be > 12
end end
it "saves custom fields" do it "saves custom fields" do

Datei anzeigen

@ -3,12 +3,7 @@ require_relative '../../../plugin_helper'
describe CustomWizard::AdminManagerController do describe CustomWizard::AdminManagerController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
let(:template) { get_wizard_fixture("wizard") }
let(:template) {
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
}
before do before do
sign_in(admin_user) sign_in(admin_user)

Datei anzeigen

@ -0,0 +1,71 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper'
describe CustomWizard::AdminProController do
fab!(:admin_user) { Fabricate(:user, admin: true) }
def generate_payload(request_id, user_id)
uri = URI(@pro.authentication_url(user_id, request_id))
keys = @pro.authentication.get_keys(request_id)
raw_payload = {
key: "12345",
nonce: keys.nonce,
push: false,
api: UserApiKeysController::AUTH_API_VERSION
}.to_json
public_key = OpenSSL::PKey::RSA.new(keys.pem)
Base64.encode64(public_key.public_encrypt(raw_payload))
end
before do
@pro = CustomWizard::Pro.new
sign_in(admin_user)
end
it "#index" do
get "/admin/wizards/pro.json"
expect(response.parsed_body['server']).to eq(@pro.server)
expect(response.parsed_body['authentication'].deep_symbolize_keys).to eq(CustomWizard::ProAuthenticationSerializer.new(@pro.authentication, root: false).as_json)
expect(response.parsed_body['subscription'].deep_symbolize_keys).to eq(CustomWizard::ProSubscriptionSerializer.new(@pro.subscription, root: false).as_json)
end
it "#authorize" do
get "/admin/wizards/pro/authorize"
expect(response.status).to eq(302)
expect(cookies[:user_api_request_id].present?).to eq(true)
end
it "#destroy_authentication" do
request_id = SecureRandom.hex(32)
payload = generate_payload(request_id, admin_user.id)
@pro.authentication_response(request_id, payload)
delete "/admin/wizards/pro/authorize.json"
expect(response.status).to eq(200)
expect(CustomWizard::Pro.authorized?).to eq(false)
end
context "subscription" do
before do
stub_subscription_request(200, valid_subscription)
end
it "handles authentication response and the updates subscription" do
request_id = cookies[:user_api_request_id] = SecureRandom.hex(32)
payload = generate_payload(request_id, admin_user.id)
get "/admin/wizards/pro/authorize/callback", params: { payload: payload }
expect(response).to redirect_to("/admin/wizards/pro")
expect(CustomWizard::Pro.subscribed?).to eq(true)
end
it "updates the subscription" do
authenticate_pro
post "/admin/wizards/pro/subscription.json"
expect(response.status).to eq(200)
expect(CustomWizard::Pro.subscribed?).to eq(true)
end
end
end

Datei anzeigen

@ -7,12 +7,7 @@ describe CustomWizard::AdminSubmissionsController do
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
fab!(:user3) { Fabricate(:user) } fab!(:user3) { Fabricate(:user) }
let(:template) { let(:template) { get_wizard_fixture("wizard") }
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
}
let(:template_2) { let(:template_2) {
temp = template.dup temp = template.dup
temp["id"] = "super_mega_fun_wizard_2" temp["id"] = "super_mega_fun_wizard_2"

Datei anzeigen

@ -5,12 +5,7 @@ describe CustomWizard::AdminWizardController do
fab!(:admin_user) { Fabricate(:user, admin: true) } fab!(:admin_user) { Fabricate(:user, admin: true) }
fab!(:user1) { Fabricate(:user) } fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
let(:template) { get_wizard_fixture("wizard") }
let(:template) {
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read)
}
before do before do
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)

Datei anzeigen

@ -2,21 +2,11 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe ApplicationController do describe ApplicationController do
fab!(:user) { fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) }
Fabricate( let(:wizard_template) { get_wizard_fixture("wizard") }
:user,
username: 'angus',
email: "angus@email.com",
trust_level: TrustLevel[3]
)
}
before do before do
CustomWizard::Template.save( CustomWizard::Template.save(wizard_template, skip_jobs: true)
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read),
skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end

Datei anzeigen

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

Datei anzeigen

@ -2,55 +2,12 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::StepsController do describe CustomWizard::StepsController do
fab!(:user) { fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) }
Fabricate( fab!(:user2) { Fabricate(:user, username: 'bob', email: "bob@email.com", trust_level: TrustLevel[2]) }
:user, let(:wizard_template) { get_wizard_fixture("wizard") }
username: 'angus', let(:wizard_field_condition_template) { get_wizard_fixture("condition/wizard_field_condition") }
email: "angus@email.com", let(:user_condition_template) { get_wizard_fixture("condition/user_condition") }
trust_level: TrustLevel[3] let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
)
}
fab!(:user2) {
Fabricate(
:user,
username: 'bob',
email: "bob@email.com",
trust_level: TrustLevel[2]
)
}
let(:wizard_template) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read
)
}
let(:wizard_field_condition_template) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/wizard_field_condition.json"
).read
)
}
let(:user_condition_template) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/user_condition.json"
).read
)
}
let(:permitted_json) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json"
).read
)
}
before do before do
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)
@ -90,17 +47,6 @@ describe CustomWizard::StepsController do
put '/w/super-mega-fun-wizard/steps/step_10.json' put '/w/super-mega-fun-wizard/steps/step_10.json'
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "when user cant see the step due to conditions" do
sign_in(user2)
new_wizard_template = wizard_template.dup
new_wizard_template['steps'][0]['condition'] = user_condition_template['condition']
CustomWizard::Template.save(new_wizard_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json'
expect(response.status).to eq(403)
end
end end
it "works if the step has no fields" do it "works if the step has no fields" do
@ -123,64 +69,40 @@ describe CustomWizard::StepsController do
expect(response.parsed_body['wizard']['start']).to eq("step_2") expect(response.parsed_body['wizard']['start']).to eq("step_2")
end end
it "returns an updated wizard when condition doesnt pass" do
new_template = wizard_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: {
step_1_field_1: "Condition wont pass"
}
}
expect(response.status).to eq(200)
expect(response.parsed_body['wizard']['start']).to eq("step_3")
end
it "runs completion actions if user has completed wizard" do it "runs completion actions if user has completed wizard" do
new_template = wizard_template.dup new_template = wizard_template.dup
## route_to action ## route_to action
new_template['actions'].last['run_after'] = 'wizard_completion' new_template['actions'].last['run_after'] = 'wizard_completion'
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition']
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put '/w/super-mega-fun-wizard/steps/step_1.json'
fields: { put '/w/super-mega-fun-wizard/steps/step_2.json'
step_1_field_1: "Condition wont pass" put '/w/super-mega-fun-wizard/steps/step_3.json'
}
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['redirect_on_complete']).to eq("https://google.com") expect(response.parsed_body['redirect_on_complete']).to eq("https://google.com")
end end
it "saves results of completion actions if user has completed wizard" do it "saves results of completion actions if user has completed wizard" do
new_template = wizard_template.dup new_template = wizard_template.dup
## Create group action
new_template['actions'].first['run_after'] = 'wizard_completion' new_template['actions'].first['run_after'] = 'wizard_completion'
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true) CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: { fields: {
step_1_field_1: "My cool group" step_1_field_1: "Topic title",
step_1_field_2: "Topic post"
} }
} }
expect(response.status).to eq(200) put '/w/super-mega-fun-wizard/steps/step_2.json'
put '/w/super-mega-fun-wizard/steps/step_3.json' put '/w/super-mega-fun-wizard/steps/step_3.json'
expect(response.status).to eq(200)
wizard_id = response.parsed_body['wizard']['id'] wizard_id = response.parsed_body['wizard']['id']
wizard = CustomWizard::Wizard.create(wizard_id, user) wizard = CustomWizard::Wizard.create(wizard_id, user)
group_name = wizard.submissions.first.fields['action_9'] topic_id = wizard.submissions.first.fields[new_template['actions'].first['id']]
group = Group.find_by(name: group_name) topic = Topic.find(topic_id)
expect(topic.present?).to eq(true)
expect(group.present?).to eq(true)
expect(group.full_name).to eq("My cool group")
end end
it "returns a final step without conditions" do it "returns a final step without conditions" do
@ -197,88 +119,119 @@ describe CustomWizard::StepsController do
expect(response.parsed_body['final']).to eq(true) expect(response.parsed_body['final']).to eq(true)
end end
it "returns the correct final step when the conditional final step and last step are the same" do context "pro" do
new_template = wizard_template.dup before do
new_template['steps'][0]['condition'] = user_condition_template['condition'] enable_pro
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition'] end
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { it "raises an error when user cant see the step due to conditions" do
fields: { sign_in(user2)
step_1_field_1: "Condition will pass"
new_wizard_template = wizard_template.dup
new_wizard_template['steps'][0]['condition'] = user_condition_template['condition']
CustomWizard::Template.save(new_wizard_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json'
expect(response.status).to eq(403)
end
it "returns an updated wizard when condition doesnt pass" do
new_template = wizard_template.dup
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: {
step_1_field_1: "Condition wont pass"
}
} }
} expect(response.status).to eq(200)
expect(response.status).to eq(200) expect(response.parsed_body['wizard']['start']).to eq("step_3")
expect(response.parsed_body['final']).to eq(false) end
put '/w/super-mega-fun-wizard/steps/step_2.json' it "returns the correct final step when the conditional final step and last step are the same" do
expect(response.status).to eq(200) new_template = wizard_template.dup
expect(response.parsed_body['final']).to eq(false) new_template['steps'][0]['condition'] = user_condition_template['condition']
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_3.json' put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
expect(response.status).to eq(200) fields: {
expect(response.parsed_body['final']).to eq(true) step_1_field_1: "Condition will pass"
end }
it "returns the correct final step when the conditional final step and last step are different" do
new_template = wizard_template.dup
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: {
step_1_field_1: "Condition will not pass"
} }
} expect(response.status).to eq(200)
expect(response.status).to eq(200) expect(response.parsed_body['final']).to eq(false)
expect(response.parsed_body['final']).to eq(false)
put '/w/super-mega-fun-wizard/steps/step_2.json' put '/w/super-mega-fun-wizard/steps/step_2.json'
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(true) expect(response.parsed_body['final']).to eq(false)
end
it "returns the correct final step when the conditional final step is determined in the same action" do put '/w/super-mega-fun-wizard/steps/step_3.json'
new_template = wizard_template.dup expect(response.status).to eq(200)
new_template['steps'][1]['condition'] = wizard_field_condition_template['condition'] expect(response.parsed_body['final']).to eq(true)
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition'] end
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { it "returns the correct final step when the conditional final step and last step are different" do
fields: { new_template = wizard_template.dup
step_1_field_1: "Condition will not pass" new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: {
step_1_field_1: "Condition will not pass"
}
} }
} expect(response.status).to eq(200)
expect(response.status).to eq(200) expect(response.parsed_body['final']).to eq(false)
expect(response.parsed_body['final']).to eq(true)
end
it "excludes the non-included conditional fields from the submissions" do put '/w/super-mega-fun-wizard/steps/step_2.json'
new_template = wizard_template.dup expect(response.status).to eq(200)
new_template['steps'][1]['fields'][0]['condition'] = wizard_field_condition_template['condition'] expect(response.parsed_body['final']).to eq(true)
CustomWizard::Template.save(new_template, skip_jobs: true) end
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { it "returns the correct final step when the conditional final step is determined in the same action" do
fields: { new_template = wizard_template.dup
step_1_field_1: "Condition will pass" new_template['steps'][1]['condition'] = wizard_field_condition_template['condition']
new_template['steps'][2]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: {
step_1_field_1: "Condition will not pass"
}
} }
} expect(response.status).to eq(200)
expect(response.parsed_body['final']).to eq(true)
end
put '/w/super-mega-fun-wizard/steps/step_2.json', params: { it "excludes the non-included conditional fields from the submissions" do
fields: { new_template = wizard_template.dup
step_2_field_1: "1995-04-23" new_template['steps'][1]['fields'][0]['condition'] = wizard_field_condition_template['condition']
CustomWizard::Template.save(new_template, skip_jobs: true)
put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
fields: {
step_1_field_1: "Condition will pass"
}
} }
}
put '/w/super-mega-fun-wizard/steps/step_1.json', params: { put '/w/super-mega-fun-wizard/steps/step_2.json', params: {
fields: { fields: {
step_1_field_1: "Condition will not pass" step_2_field_1: "1995-04-23"
}
} }
}
wizard_id = response.parsed_body['wizard']['id'] put '/w/super-mega-fun-wizard/steps/step_1.json', params: {
wizard = CustomWizard::Wizard.create(wizard_id, user) fields: {
submission = wizard.current_submission step_1_field_1: "Condition will not pass"
expect(submission.fields.keys).not_to include("step_2_field_1") }
}
wizard_id = response.parsed_body['wizard']['id']
wizard = CustomWizard::Wizard.create(wizard_id, user)
submission = wizard.current_submission
expect(submission.fields.keys).not_to include("step_2_field_1")
end
end end
end end

Datei anzeigen

@ -2,29 +2,12 @@
require_relative '../../plugin_helper' require_relative '../../plugin_helper'
describe CustomWizard::WizardController do describe CustomWizard::WizardController do
fab!(:user) { fab!(:user) { Fabricate(:user, username: 'angus', email: "angus@email.com", trust_level: TrustLevel[3]) }
Fabricate( let(:wizard_template) { get_wizard_fixture("wizard") }
:user, let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
username: 'angus',
email: "angus@email.com",
trust_level: TrustLevel[3]
)
}
let(:permitted_json) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard/permitted.json"
).read
)
}
before do before do
CustomWizard::Template.save( CustomWizard::Template.save(wizard_template, skip_jobs: true)
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read),
skip_jobs: true)
@template = CustomWizard::Template.find("super_mega_fun_wizard") @template = CustomWizard::Template.find("super_mega_fun_wizard")
sign_in(user) sign_in(user)
end end

Datei anzeigen

@ -4,13 +4,10 @@ require_relative '../../plugin_helper'
describe CustomWizard::BasicWizardSerializer do describe CustomWizard::BasicWizardSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template) { get_wizard_fixture("wizard") }
it 'should return basic wizard attributes' do it 'should return basic wizard attributes' do
CustomWizard::Template.save( CustomWizard::Template.save(template, skip_jobs: true)
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read),
skip_jobs: true)
json = CustomWizard::BasicWizardSerializer.new( json = CustomWizard::BasicWizardSerializer.new(
CustomWizard::Builder.new("super_mega_fun_wizard", user).build, CustomWizard::Builder.new("super_mega_fun_wizard", user).build,
scope: Guardian.new(user) scope: Guardian.new(user)

Datei anzeigen

@ -4,12 +4,7 @@ require_relative '../../plugin_helper'
describe CustomWizard::CustomFieldSerializer do describe CustomWizard::CustomFieldSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") }
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 it 'should return custom field attributes' do
custom_field_json['custom_fields'].each do |field_json| custom_field_json['custom_fields'].each do |field_json|

Datei anzeigen

@ -0,0 +1,17 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper'
describe CustomWizard::ProAuthenticationSerializer do
fab!(:user) { Fabricate(:user) }
it 'should return pro authentication attributes' do
auth = CustomWizard::ProAuthentication.new(OpenStruct.new(key: '1234', auth_at: Time.now, auth_by: user.id))
serialized = described_class.new(auth, root: false).as_json
expect(serialized[:active]).to eq(true)
expect(serialized[:client_id]).to eq(auth.client_id)
expect(serialized[:auth_by]).to eq(auth.auth_by)
expect(serialized[:auth_at]).to eq(auth.auth_at)
end
end

Datei anzeigen

@ -0,0 +1,14 @@
# frozen_string_literal: true
require_relative '../../../plugin_helper'
describe CustomWizard::ProSubscriptionSerializer do
it 'should return pro subscription attributes' do
sub = CustomWizard::ProSubscription.new(OpenStruct.new(type: 'community', updated_at: Time.now))
serialized = described_class.new(sub, root: false).as_json
expect(serialized[:active]).to eq(true)
expect(serialized[:type]).to eq('community')
expect(serialized[:updated_at]).to eq(sub.updated_at)
end
end

Datei anzeigen

@ -0,0 +1,14 @@
# frozen_string_literal: true
require_relative '../../plugin_helper'
describe CustomWizard::ProSerializer do
it 'should return pro attributes' do
pro = CustomWizard::Pro.new
serialized = described_class.new(pro, root: false)
expect(serialized.server).to eq(pro.server)
expect(serialized.authentication.class).to eq(CustomWizard::ProAuthentication)
expect(serialized.subscription.class).to eq(CustomWizard::ProSubscription)
end
end

Datei anzeigen

@ -4,13 +4,10 @@ require_relative '../../plugin_helper'
describe CustomWizard::FieldSerializer do describe CustomWizard::FieldSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:template) { get_wizard_fixture("wizard") }
before do before do
CustomWizard::Template.save( CustomWizard::Template.save(template, skip_jobs: true)
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read),
skip_jobs: true)
@wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build @wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build
end end

Datei anzeigen

@ -5,19 +5,11 @@ require_relative '../../plugin_helper'
describe CustomWizard::WizardSerializer do describe CustomWizard::WizardSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
fab!(:category) { Fabricate(:category) } fab!(:category) { Fabricate(:category) }
let(:template) { get_wizard_fixture("wizard") }
let(:similar_topics_validation) { let(:similar_topics_validation) { get_wizard_fixture("field/validation/similar_topics") }
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/field/validation/similar_topics.json"
).read)
}
before do before do
CustomWizard::Template.save( CustomWizard::Template.save(template, skip_jobs: true)
JSON.parse(File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read),
skip_jobs: true)
@template = CustomWizard::Template.find('super_mega_fun_wizard') @template = CustomWizard::Template.find('super_mega_fun_wizard')
end end

Datei anzeigen

@ -4,22 +4,8 @@ require_relative '../../plugin_helper'
describe CustomWizard::StepSerializer do describe CustomWizard::StepSerializer do
fab!(:user) { Fabricate(:user) } fab!(:user) { Fabricate(:user) }
let(:wizard_template) { get_wizard_fixture("wizard") }
let(:wizard_template) { let(:required_data_json) { get_wizard_fixture("step/required_data") }
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json"
).read
)
}
let(:required_data_json) {
JSON.parse(
File.open(
"#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/step/required_data.json"
).read
)
}
before do before do
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)