Update subscription, tests and type handling
Dieser Commit ist enthalten in:
Ursprung
7de00ca040
Commit
d351577ea3
33 geänderte Dateien mit 467 neuen und 449 gelöschten Zeilen
|
@ -2,7 +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 { generateSubscriptionContent } from "../lib/wizard";
|
||||
import { buildSubscriptionContent } from "../lib/wizard";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "tr",
|
||||
|
@ -38,12 +38,12 @@ export default Component.extend({
|
|||
|
||||
@discourseComputed("subscription")
|
||||
customFieldTypes(subscription) {
|
||||
return generateSubscriptionContent("custom_fields", "type", subscription);
|
||||
return buildSubscriptionContent("custom_fields", "types", subscription);
|
||||
},
|
||||
|
||||
@discourseComputed("subscription")
|
||||
customFieldKlasses(subscription) {
|
||||
return generateSubscriptionContent("custom_fields", "klass", subscription);
|
||||
return buildSubscriptionContent("custom_fields", "klass", subscription);
|
||||
},
|
||||
|
||||
@observes("field.klass")
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||
import { empty, equal, or } from "@ember/object/computed";
|
||||
import {
|
||||
buildSubscriptionContent,
|
||||
notificationLevels,
|
||||
selectKitContent,
|
||||
generateSubscriptionContent
|
||||
} from "../lib/wizard";
|
||||
import { computed } from "@ember/object";
|
||||
import UndoChanges from "../mixins/undo-changes";
|
||||
|
@ -99,6 +99,6 @@ export default Component.extend(UndoChanges, {
|
|||
|
||||
@discourseComputed("subscription")
|
||||
actionTypes(subscription) {
|
||||
return generateSubscriptionContent("action", "types", subscription);
|
||||
return buildSubscriptionContent("action", "type", subscription);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -64,7 +64,7 @@ export default {
|
|||
this.set("customWizardCriticalNotices", criticalNotices);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
api.modifyClass("component:d-navigation", {
|
||||
|
|
|
@ -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,
|
||||
|
@ -208,19 +208,25 @@ const wizardSchema = {
|
|||
step,
|
||||
field,
|
||||
custom_field,
|
||||
action
|
||||
action,
|
||||
};
|
||||
|
||||
export function hasRequiredSubscription(currentSubscriptionType, featureSubscriptionType) {
|
||||
export function hasRequiredSubscription(
|
||||
currentSubscriptionType,
|
||||
featureSubscriptionType
|
||||
) {
|
||||
const types = wizardSchema.subscription.types;
|
||||
return types.indexOf(currentSubscriptionType) >= types.indexOf(featureSubscriptionType);
|
||||
return (
|
||||
types.indexOf(currentSubscriptionType) >=
|
||||
types.indexOf(featureSubscriptionType)
|
||||
);
|
||||
}
|
||||
|
||||
export function subscriptionType(feature, attribute, value) {
|
||||
let attributes = wizardSchema.subscription.features[feature];
|
||||
export function subscriptionType(klass, attribute, value) {
|
||||
let attributes = wizardSchema.subscription.features[klass];
|
||||
|
||||
if (!attributes || !attributes[attribute] || !attributes[attribute][value]) {
|
||||
return wizardSchema.subscription_types[0];
|
||||
return wizardSchema.subscription.types[0];
|
||||
} else {
|
||||
return attributes[attribute][value];
|
||||
}
|
||||
|
@ -228,7 +234,12 @@ export function subscriptionType(feature, attribute, value) {
|
|||
|
||||
export function buildSchema(model) {
|
||||
wizardSchema.subscription = {};
|
||||
wizardSchema.subscription.features = model.subscription_features;
|
||||
|
||||
let features = model.subscription_features;
|
||||
features["field"]["types"] = features["field"]["type"];
|
||||
features["action"]["types"] = features["action"]["type"];
|
||||
|
||||
wizardSchema.subscription.features = features;
|
||||
wizardSchema.subscription.types = model.subscription_types;
|
||||
wizardSchema.field.types = model.field_types;
|
||||
wizardSchema.field.validations = model.realtime_validations;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import EmberObject from "@ember/object";
|
||||
import wizardSchema, {
|
||||
hasRequiredSubscription,
|
||||
subscriptionType
|
||||
subscriptionType,
|
||||
} from "./wizard-schema";
|
||||
import I18n from "I18n";
|
||||
|
||||
function selectKitContent(content) {
|
||||
return content.map((i) => ({ id: i, name: i }));
|
||||
|
@ -113,23 +114,22 @@ function wizardFieldList(steps = [], opts = {}) {
|
|||
}, []);
|
||||
}
|
||||
|
||||
function buildSubscriptionContent(feature, attribute, currentSubscription) {
|
||||
let attributes = wizardSchema[feature];
|
||||
function buildSubscriptionContent(klass, attribute, currentSubscription) {
|
||||
let attributes = wizardSchema[klass];
|
||||
let values = attributes[attribute];
|
||||
|
||||
if (typeof values === 'object') {
|
||||
values = Object.keys(values):
|
||||
if (typeof values === "object") {
|
||||
values = Object.keys(values);
|
||||
}
|
||||
|
||||
return values.map((value) => {
|
||||
let subscriptionType = subscriptionType(feature, attribute, value);
|
||||
|
||||
let type = subscriptionType(klass, attribute, value);
|
||||
return {
|
||||
id: value,
|
||||
name: I18n.t(`admin.wizard.${feature}.${attribute}.${value}`),
|
||||
subscription: subscriptionType,
|
||||
disabled: hasRequiredSubscription(currentSubscription, subscriptionType)
|
||||
}
|
||||
name: I18n.t(`admin.wizard.${klass}.${attribute}.${value}.label`),
|
||||
subscription: type,
|
||||
disabled: hasRequiredSubscription(currentSubscription, type),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -144,5 +144,5 @@ export {
|
|||
notificationLevels,
|
||||
wizardFieldList,
|
||||
sentenceCase,
|
||||
buildSubscriptionContent
|
||||
buildSubscriptionContent,
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ export default DiscourseRoute.extend({
|
|||
},
|
||||
|
||||
afterModel(model) {
|
||||
buildSchema(model)
|
||||
buildSchema(model);
|
||||
|
||||
return all([
|
||||
this._getThemes(model),
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -920,6 +920,7 @@ $error: #ef1700;
|
|||
|
||||
&:not(.subscribed) .subscription-settings {
|
||||
filter: blur(1px);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ class ::CustomWizard::CustomField
|
|||
next
|
||||
end
|
||||
|
||||
if attr == 'klass' && @subscription.subscription.can_use_feature?("custom_fields", "klass", 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.subscription.can_use_feature?("custom_fields", "type", 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
|
||||
|
||||
|
|
|
@ -19,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
|
||||
|
|
|
@ -5,16 +5,34 @@ class CustomWizard::Subscription::Subscription
|
|||
attr_reader :type,
|
||||
:updated_at
|
||||
|
||||
NONE ||= "none"
|
||||
STANDARD ||= "standard"
|
||||
BUSINESS ||= "business"
|
||||
FEATURES ||= {
|
||||
actions: {
|
||||
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: {
|
||||
create_topic: NONE,
|
||||
update_profile: NONE,
|
||||
open_composer: NONE,
|
||||
route_to: NONE,
|
||||
send_message: STANDARD,
|
||||
watch_categories: STANDARD,
|
||||
add_to_group: STANDARD,
|
||||
|
@ -23,20 +41,16 @@ class CustomWizard::Subscription::Subscription
|
|||
create_group: BUSINESS
|
||||
}
|
||||
},
|
||||
custom_fields: {
|
||||
custom_field: {
|
||||
klass: {
|
||||
topic: NONE,
|
||||
post: NONE,
|
||||
group: BUSINESS,
|
||||
category: BUSINESS
|
||||
},
|
||||
type: {
|
||||
string: NONE,
|
||||
boolean: NONE,
|
||||
integer: NONE,
|
||||
json: STANDARD
|
||||
}
|
||||
}
|
||||
},
|
||||
api: {}
|
||||
}
|
||||
|
||||
def initialize(subscription)
|
||||
|
@ -47,23 +61,33 @@ class CustomWizard::Subscription::Subscription
|
|||
end
|
||||
|
||||
def active?
|
||||
types.include?(type) && updated_at.to_datetime > (Time.zone.now - 2.hours).to_datetime
|
||||
self.class.types.include?(type) && updated_recently
|
||||
end
|
||||
|
||||
def can_use_feature?(feature, attribute, value)
|
||||
feature_type = FEATURES.dig(*[feature.to_sym, attribute.to_sym, value.to_sym])
|
||||
!feature_type || has_required_type?(feature_type)
|
||||
def updated_recently
|
||||
updated_at.to_datetime > (Time.zone.now - 2.hours).to_datetime
|
||||
end
|
||||
|
||||
def has_required_type?(t)
|
||||
t && type_index(t) >= type_index(type)
|
||||
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
|
||||
[NONE, STANDARD, BUSINESS]
|
||||
[STANDARD, BUSINESS]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
6
spec/fixtures/actions/add_to_group.json
gevendort
6
spec/fixtures/actions/add_to_group.json
gevendort
|
@ -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
23
spec/fixtures/actions/watch_categories.json
gevendort
Normale Datei
|
@ -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
33
spec/fixtures/field/content.json
gevendort
Normale Datei
|
@ -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
10
spec/fixtures/field/prefill.json
gevendort
Normale Datei
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"prefill": [
|
||||
{
|
||||
"type": "assignment",
|
||||
"output": "I am prefilled",
|
||||
"output_type": "text",
|
||||
"output_connector": "set"
|
||||
}
|
||||
]
|
||||
}
|
90
spec/fixtures/wizard.json
gevendort
90
spec/fixtures/wizard.json
gevendort
|
@ -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 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Laden …
In neuem Issue referenzieren