1
0
Fork 0

Commits vergleichen

...

6 Commits

36 geänderte Dateien mit 530 neuen und 594 gelöschten Zeilen

Datei anzeigen

@ -52,7 +52,7 @@ jobs:
- uses: actions/checkout@v2
with:
repository: discourse/discourse
ref: "${{ (github.base_ref || github.ref) }}"
ref: "tests-passed"
fetch-depth: 1
- name: Fetch Repo Name

Datei anzeigen

@ -2,29 +2,7 @@ import Component from "@ember/component";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
import { alias, equal, or } from "@ember/object/computed";
import I18n from "I18n";
import wizardSchema, {
requiringAdditionalSubscription,
subscriptionLevel,
} from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
const generateContent = function (kategory, subscription) {
let unsubscribedCustomFields = requiringAdditionalSubscription(
subscription,
"custom_fields",
kategory
);
return wizardSchema.custom_field[kategory].reduce((result, item) => {
let disabled = unsubscribedCustomFields.includes(item);
result.push({
id: item,
name: I18n.t(`admin.wizard.custom_field.${kategory}.${item}`),
subscription: subscriptionLevel(item, "custom_fields", kategory),
disabled,
});
return result;
}, []);
};
import { buildSubscriptionContent } from "../lib/wizard";
export default Component.extend({
tagName: "tr",
@ -60,12 +38,12 @@ export default Component.extend({
@discourseComputed("subscription")
customFieldTypes(subscription) {
return generateContent("type", subscription);
return buildSubscriptionContent("custom_fields", "types", subscription);
},
@discourseComputed("subscription")
customFieldKlasses(subscription) {
return generateContent("klass", subscription);
return buildSubscriptionContent("custom_fields", "klass", subscription);
},
@observes("field.klass")

Datei anzeigen

@ -1,10 +1,10 @@
import { default as discourseComputed } from "discourse-common/utils/decorators";
import wizardSchema, {
requiringAdditionalSubscription,
subscriptionLevel,
} from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
import { empty, equal, or } from "@ember/object/computed";
import { notificationLevels, selectKitContent } from "../lib/wizard";
import {
buildSubscriptionContent,
notificationLevels,
selectKitContent,
} from "../lib/wizard";
import { computed } from "@ember/object";
import UndoChanges from "../mixins/undo-changes";
import Component from "@ember/component";
@ -99,20 +99,6 @@ export default Component.extend(UndoChanges, {
@discourseComputed("subscription")
actionTypes(subscription) {
let unsubscribedActions = requiringAdditionalSubscription(
subscription,
"actions",
""
);
return Object.keys(wizardSchema.action.types).reduce((result, type) => {
let disabled = unsubscribedActions.includes(type);
result.push({
id: type,
name: I18n.t(`admin.wizard.action.${type}.label`),
subscription: subscriptionLevel(type, "actions", ""),
disabled,
});
return result;
}, []);
return buildSubscriptionContent("action", "type", subscription);
},
});

Datei anzeigen

@ -64,7 +64,7 @@ export default {
this.set("customWizardCriticalNotices", criticalNotices);
}
});
}
},
});
api.modifyClass("component:d-navigation", {

Datei anzeigen

@ -71,7 +71,7 @@ const field = {
type: null,
condition: null,
},
types: {},
type: {},
mapped: ["prefill", "content", "condition", "index"],
required: ["id", "type"],
dependent: {},
@ -84,7 +84,7 @@ const action = {
run_after: "wizard_completion",
type: null,
},
types: {
type: {
create_topic: {
title: null,
post: null,
@ -203,107 +203,46 @@ const custom_field = {
type: ["string", "boolean", "integer", "json"],
};
const subscription_levels = {
standard: {
actions: ["send_message", "add_to_group", "watch_categories"],
custom_fields: {
klass: [],
type: ["json"],
},
},
business: {
actions: ["create_category", "create_group", "send_to_api"],
custom_fields: {
klass: ["group", "category"],
type: [],
},
},
};
const wizardSchema = {
wizard,
step,
field,
custom_field,
action,
subscription_levels,
};
export function requiringAdditionalSubscription(
currentSubscription,
category,
subCategory
export function hasRequiredSubscription(
currentSubscriptionType,
featureSubscriptionType
) {
switch (category) {
case "actions":
switch (currentSubscription) {
case "business":
return [];
case "standard":
return subscription_levels["business"][category];
default:
return subscription_levels["standard"][category].concat(
subscription_levels["business"][category]
);
}
case "custom_fields":
switch (currentSubscription) {
case "business":
return [];
case "standard":
return subscription_levels["business"][category][subCategory];
default:
return subscription_levels["standard"][category][subCategory].concat(
subscription_levels["business"][category][subCategory]
);
}
default:
return [];
const types = wizardSchema.subscription.types;
return (
types.indexOf(currentSubscriptionType) >=
types.indexOf(featureSubscriptionType)
);
}
export function subscriptionType(klass, attribute, value) {
let attributes = wizardSchema.subscription.features[klass];
if (!attributes || !attributes[attribute] || !attributes[attribute][value]) {
return wizardSchema.subscription.types[0];
} else {
return attributes[attribute][value];
}
}
export function subscriptionLevel(type, category, subCategory) {
switch (category) {
case "actions":
if (subscription_levels["business"].actions.includes(type)) {
return "business";
} else {
if (subscription_levels["standard"].actions.includes(type)) {
return "standard";
} else {
return "";
}
}
case "custom_fields":
if (
subscription_levels["business"].custom_fields[subCategory].includes(
type
)
) {
return "business";
} else {
if (
subscription_levels["standard"].custom_fields[subCategory].includes(
type
)
) {
return "standard";
} else {
return "";
}
}
default:
return "";
}
}
export function buildSchema(model) {
wizardSchema.subscription = {};
export function buildFieldTypes(types) {
wizardSchema.field.types = types;
}
let features = model.subscription_features;
features["field"]["types"] = features["field"]["type"];
features["action"]["types"] = features["action"]["type"];
export function buildFieldValidations(validations) {
wizardSchema.field.validations = validations;
wizardSchema.subscription.features = features;
wizardSchema.subscription.types = model.subscription_types;
wizardSchema.field.types = model.field_types;
wizardSchema.field.validations = model.realtime_validations;
}
const siteSettings = getOwner(this).lookup("site-settings:main");

Datei anzeigen

@ -1,5 +1,9 @@
import EmberObject from "@ember/object";
import wizardSchema from "./wizard-schema";
import wizardSchema, {
hasRequiredSubscription,
subscriptionType,
} from "./wizard-schema";
import I18n from "I18n";
function selectKitContent(content) {
return content.map((i) => ({ id: i, name: i }));
@ -110,6 +114,25 @@ function wizardFieldList(steps = [], opts = {}) {
}, []);
}
function buildSubscriptionContent(klass, attribute, currentSubscription) {
let attributes = wizardSchema[klass];
let values = attributes[attribute];
if (typeof values === "object") {
values = Object.keys(values);
}
return values.map((value) => {
let type = subscriptionType(klass, attribute, value);
return {
id: value,
name: I18n.t(`admin.wizard.${klass}.${attribute}.${value}.label`),
subscription: type,
disabled: hasRequiredSubscription(currentSubscription, type),
};
});
}
export {
selectKitContent,
generateName,
@ -121,4 +144,5 @@ export {
notificationLevels,
wizardFieldList,
sentenceCase,
buildSubscriptionContent,
};

Datei anzeigen

@ -1,5 +1,5 @@
import DiscourseRoute from "discourse/routes/discourse";
import { buildFieldTypes, buildFieldValidations } from "../lib/wizard-schema";
import { buildSchema } from "../lib/wizard-schema";
import EmberObject, { set } from "@ember/object";
import { A } from "@ember/array";
import { all } from "rsvp";
@ -11,8 +11,7 @@ export default DiscourseRoute.extend({
},
afterModel(model) {
buildFieldTypes(model.field_types);
buildFieldValidations(model.realtime_validations);
buildSchema(model);
return all([
this._getThemes(model),

Datei anzeigen

@ -53,16 +53,6 @@
</div>
<div class="wizard-settings">
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.required"}}</label>
</div>
<div class="setting-value">
{{input type="checkbox" checked=wizard.required}}
<span>{{i18n "admin.wizard.required_label"}}</span>
</div>
</div>
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.after_signup"}}</label>
@ -83,6 +73,26 @@
</div>
</div>
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.save_submissions"}}</label>
</div>
<div class="setting-value">
{{input type="checkbox" checked=wizard.save_submissions}}
<span>{{i18n "admin.wizard.save_submissions_label"}}</span>
</div>
</div>
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.restart_on_revisit"}}</label>
</div>
<div class="setting-value">
{{input type="checkbox" checked=wizard.restart_on_revisit}}
<span>{{i18n "admin.wizard.restart_on_revisit_label"}}</span>
</div>
</div>
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.prompt_completion"}}</label>
@ -93,7 +103,7 @@
</div>
</div>
<div class="setting full-inline">
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.after_time"}}</label>
</div>
@ -108,42 +118,32 @@
</div>
</div>
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.permitted"}}</label>
</div>
<div class="setting-value">
{{wizard-mapper
inputs=wizard.permitted
options=(hash
context="wizard"
inputTypes="assignment,validation"
groupSelection="output"
userFieldSelection="key"
textSelection="value"
inputConnector="and"
)}}
</div>
</div>
{{#subscription-container subscribed=subscribed}}
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.save_submissions"}}</label>
<label>{{i18n "admin.wizard.required"}}</label>
</div>
<div class="setting-value">
{{input type="checkbox" checked=wizard.save_submissions}}
<span>{{i18n "admin.wizard.save_submissions_label"}}</span>
{{input type="checkbox" checked=wizard.required}}
<span>{{i18n "admin.wizard.required_label"}}</span>
</div>
</div>
<div class="setting">
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.restart_on_revisit"}}</label>
<label>{{i18n "admin.wizard.permitted"}}</label>
</div>
<div class="setting-value">
{{input type="checkbox" checked=wizard.restart_on_revisit}}
<span>{{i18n "admin.wizard.restart_on_revisit_label"}}</span>
{{wizard-mapper
inputs=wizard.permitted
options=(hash
context="wizard"
inputTypes="assignment,validation"
groupSelection="output"
userFieldSelection="key"
textSelection="value"
inputConnector="and"
)}}
</div>
</div>
{{/subscription-container}}

Datei anzeigen

@ -19,7 +19,7 @@
<div class="setting-label">
<label>{{i18n "admin.wizard.field.required"}}</label>
</div>
<div class="setting-value">
<span>{{i18n "admin.wizard.field.required_label"}}</span>
{{input type="checkbox" checked=field.required}}
@ -54,7 +54,7 @@
<div class="setting-label">
<label>{{i18n "admin.wizard.type"}}</label>
</div>
<div class="setting-value">
{{combo-box
value=field.type
@ -220,10 +220,10 @@
options=fieldConditionOptions}}
</div>
</div>
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.index"}}</label>>
<label>{{i18n "admin.wizard.index"}}</label>
</div>
<div class="setting-value">
@ -234,12 +234,11 @@
</div>
{{#if isCategory}}
<div class="setting pro">
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.field.property"}}</label>
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
</div>
<div class="setting-value">
{{combo-box
value=field.property

Datei anzeigen

@ -56,10 +56,9 @@
</div>
</div>
<div class="setting full field-mapper-setting pro">
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.step.required_data.label"}}</label>
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
</div>
<div class="setting-value">
{{wizard-mapper

Datei anzeigen

@ -920,6 +920,7 @@ $error: #ef1700;
&:not(.subscribed) .subscription-settings {
filter: blur(1px);
pointer-events: none;
}
}

Datei anzeigen

@ -47,7 +47,7 @@ en:
value: "Value"
profile: "profile"
type: "Type"
none: "Make a selection"
none: "Make a selection"
submission_key: 'submission key'
param_key: 'param'
group: "Group"
@ -126,9 +126,9 @@ en:
hide: "Hide"
preview: "{{action}} Preview"
popover: "{{action}} Fields"
input:
conditional:
conditional:
name: 'if'
output: 'then'
assignment:
@ -137,7 +137,7 @@ en:
name: 'map'
validation:
name: 'ensure'
selector:
label:
text: "text"
@ -175,7 +175,7 @@ en:
dependent: "{{property}} is dependent on {{dependent}}"
conflict: "{{type}} with {{property}} '{{value}}' already exists"
after_time: "After time invalid"
step:
header: "Steps"
title: "Title"
@ -189,7 +189,7 @@ en:
force_final:
label: "Conditional Final Step"
description: "Display this step as the final step if conditions on later steps have not passed when the user reaches this step."
field:
header: "Fields"
label: "Label"
@ -211,7 +211,7 @@ en:
property: "Property"
prefill: "Prefill"
content: "Content"
date_time_format:
date_time_format:
label: "Format"
instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>"
validations:
@ -228,7 +228,7 @@ en:
weeks: "Weeks"
months: "Months"
years: "Years"
type:
text: "Text"
textarea: Textarea
@ -247,7 +247,7 @@ en:
date: Date
time: Time
date_time: Date & Time
connector:
and: "and"
or: "or"
@ -261,7 +261,7 @@ en:
regex: '=~'
association: '→'
is: 'is'
action:
header: "Actions"
include: "Include Fields"
@ -269,8 +269,7 @@ en:
post: "Post"
topic_attr: "Topic Attribute"
interpolate_fields: "Insert wizard fields using the field_id in w{}. Insert user fields using field key in u{}."
run_after:
run_after:
label: "Run After"
wizard_completion: "Wizard Completion"
custom_fields:
@ -282,81 +281,83 @@ en:
suppress_notifications:
label: "Suppress Notifications"
description: "Suppress normal notifications triggered by post creation"
send_message:
label: "Send Message"
recipient: "Recipient"
create_topic:
label: "Create Topic"
category: "Category"
tags: "Tags"
visible: "Visible"
open_composer:
label: "Open Composer"
update_profile:
label: "Update Profile"
setting: "Fields"
key: "field"
watch_categories:
label: "Watch Categories"
categories: "Categories"
mute_remainder: "Mute Remainder"
notification_level:
label: "Notification Level"
regular: "Normal"
watching: "Watching"
tracking: "Tracking"
watching_first_post: "Watching First Post"
muted: "Muted"
select_a_notification_level: "Select level"
wizard_user: "Wizard User"
usernames: "Users"
post_builder:
checkbox: "Post Builder"
label: "Builder"
user_properties: "User Properties"
wizard_fields: "Wizard Fields"
wizard_actions: "Wizard Actions"
placeholder: "Insert wizard fields using the field_id in w{}. Insert user properties using property in u{}."
add_to_group:
label: "Add to Group"
route_to:
label: "Route To"
url: "Url"
code: "Code"
send_to_api:
label: "Send to API"
api: "API"
endpoint: "Endpoint"
select_an_api: "Select an API"
select_an_endpoint: "Select an endpoint"
body: "Body"
body_placeholder: "JSON"
create_category:
label: "Create Category"
name: Name
slug: Slug
color: Color
text_color: Text color
parent_category: Parent Category
permissions: Permissions
create_group:
label: Create Group
name: Name
full_name: Full Name
title: Title
bio_raw: About
owner_usernames: Owners
usernames: Members
grant_trust_level: Automatic Trust Level
mentionable_level: Mentionable Level
messageable_level: Messageable Level
visibility_level: Visibility Level
members_visibility_level: Members Visibility Level
type:
send_message:
label: "Send Message"
recipient: "Recipient"
create_topic:
label: "Create Topic"
category: "Category"
tags: "Tags"
visible: "Visible"
open_composer:
label: "Open Composer"
update_profile:
label: "Update Profile"
setting: "Fields"
key: "field"
watch_categories:
label: "Watch Categories"
categories: "Categories"
mute_remainder: "Mute Remainder"
notification_level:
label: "Notification Level"
regular: "Normal"
watching: "Watching"
tracking: "Tracking"
watching_first_post: "Watching First Post"
muted: "Muted"
select_a_notification_level: "Select level"
wizard_user: "Wizard User"
usernames: "Users"
post_builder:
checkbox: "Post Builder"
label: "Builder"
user_properties: "User Properties"
wizard_fields: "Wizard Fields"
wizard_actions: "Wizard Actions"
placeholder: "Insert wizard fields using the field_id in w{}. Insert user properties using property in u{}."
add_to_group:
label: "Add to Group"
route_to:
label: "Route To"
url: "Url"
code: "Code"
send_to_api:
label: "Send to API"
api: "API"
endpoint: "Endpoint"
select_an_api: "Select an API"
select_an_endpoint: "Select an endpoint"
body: "Body"
body_placeholder: "JSON"
create_category:
label: "Create Category"
name: Name
slug: Slug
color: Color
text_color: Text color
parent_category: Parent Category
permissions: Permissions
create_group:
label: Create Group
name: Name
full_name: Full Name
title: Title
bio_raw: About
owner_usernames: Owners
usernames: Members
grant_trust_level: Automatic Trust Level
mentionable_level: Mentionable Level
messageable_level: Messageable Level
visibility_level: Visibility Level
members_visibility_level: Members Visibility Level
custom_field:
nav_label: "Custom Fields"
add: "Add"
external:
external:
label: "from another plugin"
title: "This custom field has been added by another plugin. You can use it in your wizards but you can't edit the field here."
name:
@ -385,7 +386,7 @@ en:
basic_category: "Category"
basic_group: "Group"
post: "Post"
submissions:
nav_label: "Submissions"
title: "{{name}} Submissions"
@ -467,7 +468,7 @@ en:
subscription_container:
title: Subscriber Features
subscribed:
subscribed:
label: Subscribed
title: You're subscribed and can use these features
not_subscribed:
@ -635,7 +636,7 @@ en:
yourself_confirm:
title: "Did you forget to add recipients?"
body: "Right now this message is only being sent to yourself!"
realtime_validations:
similar_topics:
insufficient_characters: "Type a minimum 5 characters to start looking for similar topics"

Datei anzeigen

@ -6,7 +6,7 @@ en:
wizard:
custom_title: "Wizard"
custom_field:
error:
required_attribute: "'%{attr}' is a required attribute"
@ -18,7 +18,7 @@ en:
name_already_taken: "'%{name}' is already taken as a custom field name"
save_default: "Failed to save custom field '%{name}'"
subscription_type: "%{type} custom fields require a subscription"
field:
too_short: "%{label} must be at least %{min} characters"
too_long: "%{label} must not be more than %{max} characters"
@ -27,30 +27,30 @@ en:
invalid_file: "%{label} must be a %{types}"
invalid_date: "Invalid date"
invalid_time: "Invalid time"
none: "We couldn't find a wizard at that address."
no_skip: "Wizard can't be skipped"
export:
error:
select_one: "Please select at least one valid wizard"
invalid_wizards: "No valid wizards selected"
import:
error:
no_file: "No file selected"
file_large: "File too large"
invalid_json: "File is not a valid json file"
destroy:
error:
no_template: No template found
default: Error destroying wizard
validation:
required: "%{property} is required"
required: "%{attribute} is required"
conflict: "Wizard with id '%{wizard_id}' already exists"
after_time: "After time setting is invalid"
subscription: "%{type} %{property} is subscription only"
subscription: "%{class} %{attribute} is subscription only"
notice:
connection_error: "Failed to connect to http://%{domain}"
@ -62,7 +62,7 @@ en:
title: Unable to connect to the Custom Wizard Plugin status server
message: Please check the Custom Wizard Plugin status on [%{domain}](http://%{domain}) before updating Discourse. If this issue persists contact <a href="mailto:support@thepavilion.io">support@thepavilion.io</a> for further assistance.
subscription_message:
connection_error:
connection_error:
title: Unable to connect to the Custom Wizard Plugin subscription server
message: If this issue persists contact <a href="mailto:support@thepavilion.io">support@thepavilion.io</a> for further assistance.

Datei anzeigen

@ -12,7 +12,9 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
realtime_validations: CustomWizard::RealtimeValidation.types,
custom_fields: custom_field_list,
subscribed: CustomWizard::Subscription.subscribed?,
subscription: CustomWizard::Subscription.type
subscription: CustomWizard::Subscription.type,
subscription_features: CustomWizard::Subscription::Subscription::FEATURES,
subscription_types: CustomWizard::Subscription::Subscription.types
)
end

Datei anzeigen

@ -84,7 +84,7 @@ class ::CustomWizard::CustomField
next
end
if attr == 'klass' && @subscription.requires_additional_subscription("custom_fields", "klass").include?(value)
if attr == 'klass' && !@subscription.can_use_feature?("custom_field", "klass", value)
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
end
@ -99,7 +99,7 @@ class ::CustomWizard::CustomField
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
end
if attr == 'type' && @subscription.requires_additional_subscription("custom_fields", "type").include?(value)
if attr == 'type' && !@subscription.can_use_feature?("custom_field", "type", value)
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
end

Datei anzeigen

@ -6,23 +6,6 @@ class CustomWizard::Subscription
attr_accessor :authentication,
:subscription
SUBSCRIPTION_LEVELS = {
standard: {
actions: ["send_message", "add_to_group", "watch_categories"],
custom_fields: {
klass: [],
type: ["json"],
},
},
business: {
actions: ["create_category", "create_group", "send_to_api"],
custom_fields: {
klass: ["group", "category"],
type: [],
},
},
}
def initialize
@authentication = CustomWizard::Subscription::Authentication.new(get_authentication)
@subscription = CustomWizard::Subscription::Subscription.new(get_subscription)
@ -36,6 +19,11 @@ class CustomWizard::Subscription
@subscription.active?
end
def can_use_feature?(klass, attribute, value)
t = @subscription.determine_feature_subscription_type(klass, attribute, value)
!t || @subscription.has_required_type?(t)
end
def server
"test.thepavilion.io"
end
@ -56,31 +44,6 @@ class CustomWizard::Subscription
"discourse-subscription-server:user_subscription"
end
def requires_additional_subscription(kategory, sub_kategory)
case kategory
when "actions"
case self.type
when "business"
[]
when "standard"
SUBSCRIPTION_LEVELS[:business][kategory.to_sym]
else
SUBSCRIPTION_LEVELS[:standard][kategory.to_sym] + SUBSCRIPTION_LEVELS[:business][kategory.to_sym]
end
when "custom_fields"
case self.type
when "business"
[]
when "standard"
SUBSCRIPTION_LEVELS[:business][kategory.to_sym][sub_kategory.to_sym]
else
SUBSCRIPTION_LEVELS[:standard][kategory.to_sym][sub_kategory.to_sym] + SUBSCRIPTION_LEVELS[:business][kategory.to_sym][sub_kategory.to_sym]
end
else
[]
end
end
def update
if @authentication.active?
response = Excon.get(
@ -169,10 +132,6 @@ class CustomWizard::Subscription
self.new.type
end
def self.requires_additional_subscription(kategory, sub_kategory)
self.new.requires_additional_subscription(kategory, sub_kategory)
end
def self.authorized?
self.new.authorized?
end

Datei anzeigen

@ -5,6 +5,54 @@ class CustomWizard::Subscription::Subscription
attr_reader :type,
:updated_at
STANDARD ||= "standard"
BUSINESS ||= "business"
FEATURES ||= {
wizard: {
permitted: STANDARD
},
step: {
index: STANDARD,
condition: STANDARD,
required_data: BUSINESS,
permitted_params: BUSINESS
},
field: {
index: STANDARD,
condition: STANDARD,
prefill: STANDARD,
content: STANDARD,
validations: STANDARD,
type: {
tag: STANDARD,
category: STANDARD,
group: STANDARD,
composer: STANDARD,
composer_preview: STANDARD
}
},
action: {
type: {
send_message: STANDARD,
watch_categories: STANDARD,
add_to_group: STANDARD,
send_to_api: BUSINESS,
create_category: BUSINESS,
create_group: BUSINESS
}
},
custom_field: {
klass: {
group: BUSINESS,
category: BUSINESS
},
type: {
json: STANDARD
}
},
api: {}
}
def initialize(subscription)
if subscription
@type = subscription.type
@ -12,11 +60,34 @@ class CustomWizard::Subscription::Subscription
end
end
def types
%w(none standard business)
def active?
self.class.types.include?(type) && updated_recently
end
def active?
types.include?(type) && updated_at.to_datetime > (Time.zone.now - 2.hours).to_datetime
def updated_recently
updated_at.to_datetime > (Time.zone.now - 2.hours).to_datetime
end
def has_required_type?(t)
t && type && type_index(type) >= type_index(t)
end
def type_index(t)
self.class.types.index(t)
end
def determine_feature_subscription_type(klass, attribute, value)
return BUSINESS if klass.to_sym === :api
type = FEATURES.dig(*[klass.to_sym, attribute.to_sym])
if type.is_a?(Hash) && value.present?
type = type[value.to_sym]
else
type
end
end
def self.types
[STANDARD, BUSINESS]
end
end

Datei anzeigen

@ -13,34 +13,26 @@ class CustomWizard::TemplateValidator
data = @data
check_id(data, :wizard)
check_required(data, :wizard)
validate_after_time
validate_subscription(data, :wizard)
validate_class(data, :wizard)
data[:steps].each do |step|
check_required(step, :step)
validate_subscription(step, :step)
validate_class(step, :step)
if step[:fields].present?
step[:fields].each do |field|
validate_subscription(field, :field)
check_required(field, :field)
validate_class(field, :field)
end
end
end
if data[:actions].present?
data[:actions].each do |action|
validate_subscription(action, :action)
check_required(action, :action)
validate_class(action, :action)
end
end
if errors.any?
false
else
true
end
!errors.any?
end
def self.required
@ -52,56 +44,25 @@ class CustomWizard::TemplateValidator
}
end
def self.subscription
{
wizard: {
save_submissions: 'false',
restart_on_revisit: 'true',
},
step: {
condition: 'present',
index: 'conditional',
required_data: 'present',
permitted_params: 'present'
},
field: {
condition: 'present',
index: 'conditional'
},
action: {
type: %w[
send_message
add_to_group
create_category
create_group
send_to_api
]
}
}
end
private
def check_required(object, type)
self.class.required[type].each do |property|
if object[property].blank?
errors.add :base, I18n.t("wizard.validation.required", property: property)
def validate_class(object, klass)
check_required(object, klass)
validate_subscription(object, klass)
end
def check_required(object, klass)
self.class.required[klass].each do |attribute|
if object[attribute].blank?
errors.add :base, I18n.t("wizard.validation.required", attribute: attribute)
end
end
end
def validate_subscription(object, type)
self.class.subscription[type].each do |property, subscription_type|
val = object[property.to_s]
is_subscription = (val != nil) && (
subscription_type === 'present' && val.present? ||
(['true', 'false'].include?(subscription_type) && cast_bool(val) == cast_bool(subscription_type)) ||
(subscription_type === 'conditional' && val.is_a?(Hash)) ||
(subscription_type.is_a?(Array) && subscription_type.include?(val))
)
if is_subscription && !@subscription.subscribed?
errors.add :base, I18n.t("wizard.validation.subscription", type: type.to_s, property: property)
def validate_subscription(object, klass)
object.keys.each do |attribute|
if !@subscription.can_use_feature?(klass, attribute, object[attribute])
errors.add :base, I18n.t("wizard.validation.subscription", class: klass.to_s, attribute: attribute)
end
end
end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true
# name: discourse-custom-wizard
# about: Create custom wizards for topic creation, onboarding, user surveys and much more.
# version: 1.16.3
# version: 1.16.4
# authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George
# contact_emails: support@thepavilion.io
# url: https://github.com/paviliondev/discourse-custom-wizard

Datei anzeigen

@ -12,6 +12,7 @@ describe CustomWizard::Action do
let(:create_group) { get_wizard_fixture("actions/create_group") }
let(:add_to_group) { get_wizard_fixture("actions/add_to_group") }
let(:send_message) { get_wizard_fixture("actions/send_message") }
let(:watch_categories) { get_wizard_fixture("actions/watch_categories") }
let(:send_message_multi) { get_wizard_fixture("actions/send_message_multi") }
let(:api_test_endpoint) { get_wizard_fixture("endpoints/test_endpoint") }
let(:api_test_endpoint_body) { get_wizard_fixture("endpoints/test_endpoint_body") }
@ -159,17 +160,6 @@ describe CustomWizard::Action do
end
end
it 'watches categories' do
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, step_1_field_1: "Text input").update
wizard.create_updater(wizard.steps[1].id, {}).update
expect(CategoryUser.where(
category_id: category.id,
user_id: user.id
).first.notification_level).to eq(0)
end
it 're-routes a user' do
wizard = CustomWizard::Builder.new(@template[:id], user).build
updater = wizard.create_updater(wizard.steps.last.id, {})
@ -177,7 +167,7 @@ describe CustomWizard::Action do
expect(updater.result[:redirect_on_next]).to eq("https://google.com")
end
context "subscription actions" do
context "standard subscription actions" do
before do
enable_subscription("standard")
end
@ -235,6 +225,38 @@ describe CustomWizard::Action do
expect(post.exists?).to eq(true)
end
it '#add_to_group' do
add_to_group["group"][0]["output"] = group.name
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
expect(group.users.first.username).to eq('angus')
end
it '#watch_categories' do
wizard_template['actions'] << watch_categories
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(CategoryUser.where(
category_id: category.id,
user_id: user.id
).first.notification_level).to eq(0)
end
end
context "business subscription actions" do
before do
enable_subscription("business")
end
it '#create_category' do
wizard_template['actions'] << create_category
update_template(wizard_template)
@ -256,19 +278,6 @@ describe CustomWizard::Action do
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
it '#send_to_api successful' do
stub_request(:put, "https://myexternalapi.com/update").
with(

Datei anzeigen

@ -20,6 +20,7 @@ describe CustomWizard::Builder do
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
let(:permitted_param_json) { get_wizard_fixture("step/permitted_params") }
let(:user_condition_json) { get_wizard_fixture("condition/user_condition") }
let(:prefill_json) { get_wizard_fixture("field/prefill") }
let(:boolean_field_condition_json) {
JSON.parse(
@ -35,6 +36,12 @@ describe CustomWizard::Builder do
@template = CustomWizard::Template.find('super_mega_fun_wizard')
end
def perform_update(step_id, submission)
updater = @wizard.create_updater(step_id, submission)
updater.update
updater
end
context 'disabled' do
before do
SiteSetting.custom_wizard_enabled = false
@ -101,6 +108,7 @@ describe CustomWizard::Builder do
context "with restricted permissions" do
before do
enable_subscription("standard")
@template[:permitted] = permitted_json["permitted"]
CustomWizard::Template.save(@template.as_json)
end
@ -155,13 +163,21 @@ describe CustomWizard::Builder do
end
end
it 'returns prefilled data' do
expect(
CustomWizard::Builder.new(@template[:id], user).build
.steps.first
.fields.first
.value
).to eq('I am prefilled')
context "prefilled data" do
before do
enable_subscription("standard")
@template[:steps][0][:fields][0][:prefill] = prefill_json["prefill"]
CustomWizard::Template.save(@template.as_json)
end
it "works" do
expect(
CustomWizard::Builder.new(@template[:id], user).build
.steps.first
.fields.first
.value
).to eq('I am prefilled')
end
end
context "user has partially completed" do
@ -190,12 +206,14 @@ describe CustomWizard::Builder do
end
it 'does not return saved submissions' do
@wizard = CustomWizard::Builder.new(@template[:id], user).build
perform_update('step_1', step_1_field_1: 'Text input')
expect(
CustomWizard::Builder.new(@template[:id], user).build
.steps.first
.fields.first
.value
).to eq('I am prefilled')
).to eq(nil)
end
end
end
@ -213,7 +231,7 @@ describe CustomWizard::Builder do
context 'with required data' do
before do
enable_subscription("standard")
enable_subscription("business")
@template[:steps][0][:required_data] = required_data_json['required_data']
@template[:steps][0][:required_data_message] = required_data_json['required_data_message']
CustomWizard::Template.save(@template.as_json)
@ -249,7 +267,7 @@ describe CustomWizard::Builder do
context "with permitted params" do
before do
enable_subscription("standard")
enable_subscription("business")
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
CustomWizard::Template.save(@template.as_json)
end
@ -298,14 +316,14 @@ describe CustomWizard::Builder do
.build
.steps.first
.fields.length
).to eq(4)
).to eq(3)
end
context "with condition" do
before do
enable_subscription("standard")
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
@template[:steps][2][:fields][5][:condition] = boolean_field_condition_json['condition']
@template[:steps][2][:fields][2][:condition] = boolean_field_condition_json['condition']
CustomWizard::Template.save(@template.as_json)
end
@ -326,18 +344,12 @@ describe CustomWizard::Builder do
builder = CustomWizard::Builder.new(@template[:id], user)
wizard = builder.build
expect(wizard.steps.last.fields.last.id).to eq(@template[:steps][2][:fields][5]['id'])
expect(wizard.steps.last.fields.last.id).to eq(@template[:steps][2][:fields][2]['id'])
end
end
end
context 'on update' do
def perform_update(step_id, submission)
updater = @wizard.create_updater(step_id, submission)
updater.update
updater
end
it 'saves submissions' do
@wizard = CustomWizard::Builder.new(@template[:id], user).build
perform_update('step_1', step_1_field_1: 'Text input')

Datei anzeigen

@ -48,6 +48,8 @@ describe CustomWizard::Template do
context "wizard template list" do
before do
enable_subscription("standard")
template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2'
template_json_2["permitted"] = permitted_json['permitted']

Datei anzeigen

@ -6,6 +6,7 @@ describe CustomWizard::TemplateValidator do
let(:template) { get_wizard_fixture("wizard") }
let(:create_category) { get_wizard_fixture("actions/create_category") }
let(:user_condition) { get_wizard_fixture("condition/user_condition") }
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
it "validates valid templates" do
expect(
@ -45,7 +46,7 @@ describe CustomWizard::TemplateValidator do
context "without subscription" do
it "invalidates subscription wizard attributes" do
template[:save_submissions] = false
template[:permitted] = permitted_json["permitted"]
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(false)
@ -73,13 +74,13 @@ describe CustomWizard::TemplateValidator do
end
end
context "with subscription" do
context "with standard subscription" do
before do
enable_subscription("standard")
end
it "validates wizard attributes" do
template[:save_submissions] = false
template[:permitted] = permitted_json["permitted"]
expect(
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
@ -98,6 +99,12 @@ describe CustomWizard::TemplateValidator do
CustomWizard::TemplateValidator.new(template).perform
).to eq(true)
end
end
context "with business subscription" do
before do
enable_subscription("business")
end
it "validates actions" do
template[:actions] << create_category

Datei anzeigen

@ -22,7 +22,6 @@ describe CustomWizard::UpdateValidator do
@template[:steps][0][:fields][0][:min_length] = min_length
@template[:steps][0][:fields][1][:min_length] = min_length
@template[:steps][0][:fields][2][:min_length] = min_length
CustomWizard::Template.save(@template)
@ -35,11 +34,6 @@ describe CustomWizard::UpdateValidator do
expect(
updater.errors.messages[:step_1_field_2].first
).to eq(I18n.t('wizard.field.too_short', label: 'Textarea', min: min_length))
updater = perform_validation('step_1', step_1_field_3: 'Te')
expect(
updater.errors.messages[:step_1_field_3].first
).to eq(I18n.t('wizard.field.too_short', label: 'Composer', min: min_length))
end
it 'prevents submission if the length is over the max length' do
@ -47,7 +41,6 @@ describe CustomWizard::UpdateValidator do
@template[:steps][0][:fields][0][:max_length] = max_length
@template[:steps][0][:fields][1][:max_length] = max_length
@template[:steps][0][:fields][2][:max_length] = max_length
CustomWizard::Template.save(@template)
long_string = "Our Competitive Capability solution offers platforms a suite of wholesale offerings. In the future, will you be able to effectively revolutionize synergies in your business? In the emerging market space, industry is ethically investing its mission critical executive searches. Key players will take ownership of their capabilities by iteratively right-sizing world-class visibilities. "
@ -60,11 +53,6 @@ describe CustomWizard::UpdateValidator do
expect(
updater.errors.messages[:step_1_field_2].first
).to eq(I18n.t('wizard.field.too_long', label: 'Textarea', max: max_length))
updater = perform_validation('step_1', step_1_field_3: long_string)
expect(
updater.errors.messages[:step_1_field_3].first
).to eq(I18n.t('wizard.field.too_long', label: 'Composer', max: max_length))
end
it "allows submission if the length is under or equal to the max length" do
@ -72,7 +60,6 @@ describe CustomWizard::UpdateValidator do
@template[:steps][0][:fields][0][:max_length] = max_length
@template[:steps][0][:fields][1][:max_length] = max_length
@template[:steps][0][:fields][2][:max_length] = max_length
CustomWizard::Template.save(@template)
hundred_chars_string = "This is a line, exactly hundred characters long and not more even a single character more than that."
@ -85,11 +72,6 @@ describe CustomWizard::UpdateValidator do
expect(
updater.errors.messages[:step_1_field_2].first
).to eq(nil)
updater = perform_validation('step_1', step_1_field_3: hundred_chars_string)
expect(
updater.errors.messages[:step_1_field_3].first
).to eq(nil)
end
it "applies min length only if the input is non-empty" do

Datei anzeigen

@ -14,6 +14,7 @@ describe CustomWizard::Wizard do
@permitted_template = template_json.dup
@permitted_template["permitted"] = permitted_json["permitted"]
@wizard = CustomWizard::Wizard.new(template_json, user)
enable_subscription("standard")
end
def append_steps

Datei anzeigen

@ -5,9 +5,9 @@
"group": [
{
"type": "assignment",
"output": "action_9",
"output_type": "wizard_action",
"output": "",
"output_type": "text",
"output_connector": "set"
}
]
}
}

23
spec/fixtures/actions/watch_categories.json gevendort Normale Datei
Datei anzeigen

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

33
spec/fixtures/field/content.json gevendort Normale Datei
Datei anzeigen

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

10
spec/fixtures/field/prefill.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,10 @@
{
"prefill": [
{
"type": "assignment",
"output": "I am prefilled",
"output_type": "text",
"output_connector": "set"
}
]
}

Datei anzeigen

@ -17,15 +17,7 @@
"label": "Text",
"description": "Text field description.",
"type": "text",
"min_length": "3",
"prefill": [
{
"type": "assignment",
"output": "I am prefilled",
"output_type": "text",
"output_connector": "set"
}
]
"min_length": "3"
},
{
"id": "step_1_field_2",
@ -33,11 +25,6 @@
"type": "textarea",
"min_length": ""
},
{
"id": "step_1_field_3",
"label": "Composer",
"type": "composer"
},
{
"id": "step_1_field_4",
"label": "I'm only text",
@ -102,55 +89,7 @@
{
"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"
"type": "dropdown"
},
{
"id": "step_3_field_5",
@ -257,29 +196,6 @@
}
]
},
{
"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",
"run_after": "step_2",
@ -337,4 +253,4 @@
]
}
]
}
}

Datei anzeigen

@ -33,6 +33,7 @@ def enable_subscription(type)
# CustomWizard::Subscription.new
CustomWizard::Subscription.any_instance.stubs(:subscribed?).returns(true)
CustomWizard::Subscription.any_instance.stubs(:type).returns(type)
CustomWizard::Subscription::Subscription.any_instance.stubs(:type).returns(type)
end
def disable_subscription

Datei anzeigen

@ -8,6 +8,7 @@ describe CustomWizard::AdminWizardController do
let(:template) { get_wizard_fixture("wizard") }
before do
enable_subscription("standard")
CustomWizard::Template.save(template, skip_jobs: true)
template_2 = template.dup

Datei anzeigen

@ -35,6 +35,8 @@ describe CustomWizard::StepsController do
end
it "when the user cant access the wizard" do
enable_subscription("standard")
new_template = wizard_template.dup
new_template["permitted"] = permitted_json["permitted"]
CustomWizard::Template.save(new_template, skip_jobs: true)

Datei anzeigen

@ -18,10 +18,10 @@ describe CustomWizard::FieldSerializer do
scope: Guardian.new(user)
).as_json
expect(json_array.size).to eq(4)
expect(json_array.size).to eq(3)
expect(json_array[0][:label]).to eq("<p>Text</p>")
expect(json_array[0][:description]).to eq("Text field description.")
expect(json_array[3][:index]).to eq(3)
expect(json_array[2][:index]).to eq(2)
end
it "should return optional field attributes" do

Datei anzeigen

@ -42,55 +42,73 @@ describe CustomWizard::WizardSerializer do
).to eq(BasicUserSerializer.new(user, root: false).as_json)
end
it "should not return categories if there are no category fields" do
@template[:steps][2][:fields].delete_at(2)
CustomWizard::Template.save(@template)
context "with subscription" do
before do
enable_subscription("standard")
end
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:categories].present?).to eq(false)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(false)
end
it "should not return categories if there are no category fields" do
@template[:steps][2][:fields].delete_at(2)
CustomWizard::Template.save(@template)
it "should return categories if there is a category selector field" do
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:categories].present?).to eq(true)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
end
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
it "should return categories if there is a similar topics validation scoped to category(s)" do
@template[:steps][0][:fields][0][:validations] = similar_topics_validation[:validations]
CustomWizard::Template.save(@template)
expect(json[:wizard][:categories].present?).to eq(false)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(false)
end
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:categories].present?).to eq(true)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
end
it "should return categories if there is a category selector field" do
@template[:steps][0][:fields] << { "id": "step_1_field_5", "label": "Category", "type": "category" }.as_json
CustomWizard::Template.save(@template)
it 'should return groups if there is a group selector field' do
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:groups].length).to eq(8)
end
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
it 'should not return groups if there is not a group selector field' do
@template[:steps][2][:fields].delete_at(3)
CustomWizard::Template.save(@template)
expect(json[:wizard][:categories].present?).to eq(true)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
end
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:groups].present?).to eq(false)
it "should return categories if there is a similar topics validation scoped to category(s)" do
@template[:steps][0][:fields][0][:validations] = similar_topics_validation
CustomWizard::Template.save(@template)
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:categories].present?).to eq(true)
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
end
it 'should return groups if there is a group selector field' do
@template[:steps][0][:fields] << { "id": "step_1_field_5", "label": "Group", "type": "group" }.as_json
CustomWizard::Template.save(@template)
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:groups].present?).to eq(true)
expect(json[:wizard][:groups].length).to eq(8)
end
it 'should not return groups if there is not a group selector field' do
@template[:steps][2][:fields].delete_at(3)
CustomWizard::Template.save(@template)
json = CustomWizard::WizardSerializer.new(
CustomWizard::Builder.new(@template[:id], user).build,
scope: Guardian.new(user)
).as_json
expect(json[:wizard][:groups].present?).to eq(false)
end
end
end

Datei anzeigen

@ -29,12 +29,12 @@ describe CustomWizard::StepSerializer do
each_serializer: described_class,
scope: Guardian.new(user)
).as_json
expect(json_array[0][:fields].length).to eq(4)
expect(json_array[0][:fields].length).to eq(3)
end
context 'with required data' do
before do
enable_subscription("standard")
enable_subscription("business")
wizard_template['steps'][0]['required_data'] = required_data_json['required_data']
wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message']
CustomWizard::Template.save(wizard_template)