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 discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
import { alias, equal, or } from "@ember/object/computed";
|
import { alias, equal, or } from "@ember/object/computed";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { generateSubscriptionContent } from "../lib/wizard";
|
import { buildSubscriptionContent } from "../lib/wizard";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: "tr",
|
tagName: "tr",
|
||||||
|
@ -38,12 +38,12 @@ export default Component.extend({
|
||||||
|
|
||||||
@discourseComputed("subscription")
|
@discourseComputed("subscription")
|
||||||
customFieldTypes(subscription) {
|
customFieldTypes(subscription) {
|
||||||
return generateSubscriptionContent("custom_fields", "type", subscription);
|
return buildSubscriptionContent("custom_fields", "types", subscription);
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed("subscription")
|
@discourseComputed("subscription")
|
||||||
customFieldKlasses(subscription) {
|
customFieldKlasses(subscription) {
|
||||||
return generateSubscriptionContent("custom_fields", "klass", subscription);
|
return buildSubscriptionContent("custom_fields", "klass", subscription);
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes("field.klass")
|
@observes("field.klass")
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import { empty, equal, or } from "@ember/object/computed";
|
import { empty, equal, or } from "@ember/object/computed";
|
||||||
import {
|
import {
|
||||||
|
buildSubscriptionContent,
|
||||||
notificationLevels,
|
notificationLevels,
|
||||||
selectKitContent,
|
selectKitContent,
|
||||||
generateSubscriptionContent
|
|
||||||
} from "../lib/wizard";
|
} from "../lib/wizard";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import UndoChanges from "../mixins/undo-changes";
|
import UndoChanges from "../mixins/undo-changes";
|
||||||
|
@ -99,6 +99,6 @@ export default Component.extend(UndoChanges, {
|
||||||
|
|
||||||
@discourseComputed("subscription")
|
@discourseComputed("subscription")
|
||||||
actionTypes(subscription) {
|
actionTypes(subscription) {
|
||||||
return generateSubscriptionContent("action", "types", subscription);
|
return buildSubscriptionContent("action", "type", subscription);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default {
|
||||||
this.set("customWizardCriticalNotices", criticalNotices);
|
this.set("customWizardCriticalNotices", criticalNotices);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
api.modifyClass("component:d-navigation", {
|
api.modifyClass("component:d-navigation", {
|
||||||
|
|
|
@ -71,7 +71,7 @@ const field = {
|
||||||
type: null,
|
type: null,
|
||||||
condition: null,
|
condition: null,
|
||||||
},
|
},
|
||||||
types: {},
|
type: {},
|
||||||
mapped: ["prefill", "content", "condition", "index"],
|
mapped: ["prefill", "content", "condition", "index"],
|
||||||
required: ["id", "type"],
|
required: ["id", "type"],
|
||||||
dependent: {},
|
dependent: {},
|
||||||
|
@ -84,7 +84,7 @@ const action = {
|
||||||
run_after: "wizard_completion",
|
run_after: "wizard_completion",
|
||||||
type: null,
|
type: null,
|
||||||
},
|
},
|
||||||
types: {
|
type: {
|
||||||
create_topic: {
|
create_topic: {
|
||||||
title: null,
|
title: null,
|
||||||
post: null,
|
post: null,
|
||||||
|
@ -208,19 +208,25 @@ const wizardSchema = {
|
||||||
step,
|
step,
|
||||||
field,
|
field,
|
||||||
custom_field,
|
custom_field,
|
||||||
action
|
action,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function hasRequiredSubscription(currentSubscriptionType, featureSubscriptionType) {
|
export function hasRequiredSubscription(
|
||||||
|
currentSubscriptionType,
|
||||||
|
featureSubscriptionType
|
||||||
|
) {
|
||||||
const types = wizardSchema.subscription.types;
|
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) {
|
export function subscriptionType(klass, attribute, value) {
|
||||||
let attributes = wizardSchema.subscription.features[feature];
|
let attributes = wizardSchema.subscription.features[klass];
|
||||||
|
|
||||||
if (!attributes || !attributes[attribute] || !attributes[attribute][value]) {
|
if (!attributes || !attributes[attribute] || !attributes[attribute][value]) {
|
||||||
return wizardSchema.subscription_types[0];
|
return wizardSchema.subscription.types[0];
|
||||||
} else {
|
} else {
|
||||||
return attributes[attribute][value];
|
return attributes[attribute][value];
|
||||||
}
|
}
|
||||||
|
@ -228,7 +234,12 @@ export function subscriptionType(feature, attribute, value) {
|
||||||
|
|
||||||
export function buildSchema(model) {
|
export function buildSchema(model) {
|
||||||
wizardSchema.subscription = {};
|
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.subscription.types = model.subscription_types;
|
||||||
wizardSchema.field.types = model.field_types;
|
wizardSchema.field.types = model.field_types;
|
||||||
wizardSchema.field.validations = model.realtime_validations;
|
wizardSchema.field.validations = model.realtime_validations;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import wizardSchema, {
|
import wizardSchema, {
|
||||||
hasRequiredSubscription,
|
hasRequiredSubscription,
|
||||||
subscriptionType
|
subscriptionType,
|
||||||
} from "./wizard-schema";
|
} from "./wizard-schema";
|
||||||
|
import I18n from "I18n";
|
||||||
|
|
||||||
function selectKitContent(content) {
|
function selectKitContent(content) {
|
||||||
return content.map((i) => ({ id: i, name: i }));
|
return content.map((i) => ({ id: i, name: i }));
|
||||||
|
@ -113,23 +114,22 @@ function wizardFieldList(steps = [], opts = {}) {
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSubscriptionContent(feature, attribute, currentSubscription) {
|
function buildSubscriptionContent(klass, attribute, currentSubscription) {
|
||||||
let attributes = wizardSchema[feature];
|
let attributes = wizardSchema[klass];
|
||||||
let values = attributes[attribute];
|
let values = attributes[attribute];
|
||||||
|
|
||||||
if (typeof values === 'object') {
|
if (typeof values === "object") {
|
||||||
values = Object.keys(values):
|
values = Object.keys(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
return values.map((value) => {
|
return values.map((value) => {
|
||||||
let subscriptionType = subscriptionType(feature, attribute, value);
|
let type = subscriptionType(klass, attribute, value);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: value,
|
id: value,
|
||||||
name: I18n.t(`admin.wizard.${feature}.${attribute}.${value}`),
|
name: I18n.t(`admin.wizard.${klass}.${attribute}.${value}.label`),
|
||||||
subscription: subscriptionType,
|
subscription: type,
|
||||||
disabled: hasRequiredSubscription(currentSubscription, subscriptionType)
|
disabled: hasRequiredSubscription(currentSubscription, type),
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,5 +144,5 @@ export {
|
||||||
notificationLevels,
|
notificationLevels,
|
||||||
wizardFieldList,
|
wizardFieldList,
|
||||||
sentenceCase,
|
sentenceCase,
|
||||||
buildSubscriptionContent
|
buildSubscriptionContent,
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default DiscourseRoute.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
buildSchema(model)
|
buildSchema(model);
|
||||||
|
|
||||||
return all([
|
return all([
|
||||||
this._getThemes(model),
|
this._getThemes(model),
|
||||||
|
|
|
@ -53,16 +53,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wizard-settings">
|
<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">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.after_signup"}}</label>
|
<label>{{i18n "admin.wizard.after_signup"}}</label>
|
||||||
|
@ -83,6 +73,26 @@
|
||||||
</div>
|
</div>
|
||||||
</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">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.prompt_completion"}}</label>
|
<label>{{i18n "admin.wizard.prompt_completion"}}</label>
|
||||||
|
@ -93,7 +103,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting full-inline">
|
<div class="setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.after_time"}}</label>
|
<label>{{i18n "admin.wizard.after_time"}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -108,42 +118,32 @@
|
||||||
</div>
|
</div>
|
||||||
</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}}
|
{{#subscription-container subscribed=subscribed}}
|
||||||
<div class="setting">
|
<div class="setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.save_submissions"}}</label>
|
<label>{{i18n "admin.wizard.required"}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{input type="checkbox" checked=wizard.save_submissions}}
|
{{input type="checkbox" checked=wizard.required}}
|
||||||
<span>{{i18n "admin.wizard.save_submissions_label"}}</span>
|
<span>{{i18n "admin.wizard.required_label"}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting">
|
<div class="setting full field-mapper-setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.restart_on_revisit"}}</label>
|
<label>{{i18n "admin.wizard.permitted"}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{input type="checkbox" checked=wizard.restart_on_revisit}}
|
{{wizard-mapper
|
||||||
<span>{{i18n "admin.wizard.restart_on_revisit_label"}}</span>
|
inputs=wizard.permitted
|
||||||
|
options=(hash
|
||||||
|
context="wizard"
|
||||||
|
inputTypes="assignment,validation"
|
||||||
|
groupSelection="output"
|
||||||
|
userFieldSelection="key"
|
||||||
|
textSelection="value"
|
||||||
|
inputConnector="and"
|
||||||
|
)}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/subscription-container}}
|
{{/subscription-container}}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.field.required"}}</label>
|
<label>{{i18n "admin.wizard.field.required"}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
<span>{{i18n "admin.wizard.field.required_label"}}</span>
|
<span>{{i18n "admin.wizard.field.required_label"}}</span>
|
||||||
{{input type="checkbox" checked=field.required}}
|
{{input type="checkbox" checked=field.required}}
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.type"}}</label>
|
<label>{{i18n "admin.wizard.type"}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{combo-box
|
{{combo-box
|
||||||
value=field.type
|
value=field.type
|
||||||
|
@ -220,10 +220,10 @@
|
||||||
options=fieldConditionOptions}}
|
options=fieldConditionOptions}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting full field-mapper-setting">
|
<div class="setting full field-mapper-setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.index"}}</label>>
|
<label>{{i18n "admin.wizard.index"}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
|
@ -234,12 +234,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if isCategory}}
|
{{#if isCategory}}
|
||||||
<div class="setting pro">
|
<div class="setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.field.property"}}</label>
|
<label>{{i18n "admin.wizard.field.property"}}</label>
|
||||||
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{combo-box
|
{{combo-box
|
||||||
value=field.property
|
value=field.property
|
||||||
|
|
|
@ -56,10 +56,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting full field-mapper-setting pro">
|
<div class="setting full field-mapper-setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.step.required_data.label"}}</label>
|
<label>{{i18n "admin.wizard.step.required_data.label"}}</label>
|
||||||
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{wizard-mapper
|
{{wizard-mapper
|
||||||
|
|
|
@ -920,6 +920,7 @@ $error: #ef1700;
|
||||||
|
|
||||||
&:not(.subscribed) .subscription-settings {
|
&:not(.subscribed) .subscription-settings {
|
||||||
filter: blur(1px);
|
filter: blur(1px);
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ en:
|
||||||
value: "Value"
|
value: "Value"
|
||||||
profile: "profile"
|
profile: "profile"
|
||||||
type: "Type"
|
type: "Type"
|
||||||
none: "Make a selection"
|
none: "Make a selection"
|
||||||
submission_key: 'submission key'
|
submission_key: 'submission key'
|
||||||
param_key: 'param'
|
param_key: 'param'
|
||||||
group: "Group"
|
group: "Group"
|
||||||
|
@ -126,9 +126,9 @@ en:
|
||||||
hide: "Hide"
|
hide: "Hide"
|
||||||
preview: "{{action}} Preview"
|
preview: "{{action}} Preview"
|
||||||
popover: "{{action}} Fields"
|
popover: "{{action}} Fields"
|
||||||
|
|
||||||
input:
|
input:
|
||||||
conditional:
|
conditional:
|
||||||
name: 'if'
|
name: 'if'
|
||||||
output: 'then'
|
output: 'then'
|
||||||
assignment:
|
assignment:
|
||||||
|
@ -137,7 +137,7 @@ en:
|
||||||
name: 'map'
|
name: 'map'
|
||||||
validation:
|
validation:
|
||||||
name: 'ensure'
|
name: 'ensure'
|
||||||
|
|
||||||
selector:
|
selector:
|
||||||
label:
|
label:
|
||||||
text: "text"
|
text: "text"
|
||||||
|
@ -175,7 +175,7 @@ en:
|
||||||
dependent: "{{property}} is dependent on {{dependent}}"
|
dependent: "{{property}} is dependent on {{dependent}}"
|
||||||
conflict: "{{type}} with {{property}} '{{value}}' already exists"
|
conflict: "{{type}} with {{property}} '{{value}}' already exists"
|
||||||
after_time: "After time invalid"
|
after_time: "After time invalid"
|
||||||
|
|
||||||
step:
|
step:
|
||||||
header: "Steps"
|
header: "Steps"
|
||||||
title: "Title"
|
title: "Title"
|
||||||
|
@ -189,7 +189,7 @@ en:
|
||||||
force_final:
|
force_final:
|
||||||
label: "Conditional Final Step"
|
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."
|
description: "Display this step as the final step if conditions on later steps have not passed when the user reaches this step."
|
||||||
|
|
||||||
field:
|
field:
|
||||||
header: "Fields"
|
header: "Fields"
|
||||||
label: "Label"
|
label: "Label"
|
||||||
|
@ -211,7 +211,7 @@ en:
|
||||||
property: "Property"
|
property: "Property"
|
||||||
prefill: "Prefill"
|
prefill: "Prefill"
|
||||||
content: "Content"
|
content: "Content"
|
||||||
date_time_format:
|
date_time_format:
|
||||||
label: "Format"
|
label: "Format"
|
||||||
instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>"
|
instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>"
|
||||||
validations:
|
validations:
|
||||||
|
@ -228,7 +228,7 @@ en:
|
||||||
weeks: "Weeks"
|
weeks: "Weeks"
|
||||||
months: "Months"
|
months: "Months"
|
||||||
years: "Years"
|
years: "Years"
|
||||||
|
|
||||||
type:
|
type:
|
||||||
text: "Text"
|
text: "Text"
|
||||||
textarea: Textarea
|
textarea: Textarea
|
||||||
|
@ -247,7 +247,7 @@ en:
|
||||||
date: Date
|
date: Date
|
||||||
time: Time
|
time: Time
|
||||||
date_time: Date & Time
|
date_time: Date & Time
|
||||||
|
|
||||||
connector:
|
connector:
|
||||||
and: "and"
|
and: "and"
|
||||||
or: "or"
|
or: "or"
|
||||||
|
@ -261,7 +261,7 @@ en:
|
||||||
regex: '=~'
|
regex: '=~'
|
||||||
association: '→'
|
association: '→'
|
||||||
is: 'is'
|
is: 'is'
|
||||||
|
|
||||||
action:
|
action:
|
||||||
header: "Actions"
|
header: "Actions"
|
||||||
include: "Include Fields"
|
include: "Include Fields"
|
||||||
|
@ -269,8 +269,7 @@ en:
|
||||||
post: "Post"
|
post: "Post"
|
||||||
topic_attr: "Topic Attribute"
|
topic_attr: "Topic Attribute"
|
||||||
interpolate_fields: "Insert wizard fields using the field_id in w{}. Insert user fields using field key in u{}."
|
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"
|
label: "Run After"
|
||||||
wizard_completion: "Wizard Completion"
|
wizard_completion: "Wizard Completion"
|
||||||
custom_fields:
|
custom_fields:
|
||||||
|
@ -282,81 +281,83 @@ en:
|
||||||
suppress_notifications:
|
suppress_notifications:
|
||||||
label: "Suppress Notifications"
|
label: "Suppress Notifications"
|
||||||
description: "Suppress normal notifications triggered by post creation"
|
description: "Suppress normal notifications triggered by post creation"
|
||||||
send_message:
|
|
||||||
label: "Send Message"
|
type:
|
||||||
recipient: "Recipient"
|
send_message:
|
||||||
create_topic:
|
label: "Send Message"
|
||||||
label: "Create Topic"
|
recipient: "Recipient"
|
||||||
category: "Category"
|
create_topic:
|
||||||
tags: "Tags"
|
label: "Create Topic"
|
||||||
visible: "Visible"
|
category: "Category"
|
||||||
open_composer:
|
tags: "Tags"
|
||||||
label: "Open Composer"
|
visible: "Visible"
|
||||||
update_profile:
|
open_composer:
|
||||||
label: "Update Profile"
|
label: "Open Composer"
|
||||||
setting: "Fields"
|
update_profile:
|
||||||
key: "field"
|
label: "Update Profile"
|
||||||
watch_categories:
|
setting: "Fields"
|
||||||
label: "Watch Categories"
|
key: "field"
|
||||||
categories: "Categories"
|
watch_categories:
|
||||||
mute_remainder: "Mute Remainder"
|
label: "Watch Categories"
|
||||||
notification_level:
|
categories: "Categories"
|
||||||
label: "Notification Level"
|
mute_remainder: "Mute Remainder"
|
||||||
regular: "Normal"
|
notification_level:
|
||||||
watching: "Watching"
|
label: "Notification Level"
|
||||||
tracking: "Tracking"
|
regular: "Normal"
|
||||||
watching_first_post: "Watching First Post"
|
watching: "Watching"
|
||||||
muted: "Muted"
|
tracking: "Tracking"
|
||||||
select_a_notification_level: "Select level"
|
watching_first_post: "Watching First Post"
|
||||||
wizard_user: "Wizard User"
|
muted: "Muted"
|
||||||
usernames: "Users"
|
select_a_notification_level: "Select level"
|
||||||
post_builder:
|
wizard_user: "Wizard User"
|
||||||
checkbox: "Post Builder"
|
usernames: "Users"
|
||||||
label: "Builder"
|
post_builder:
|
||||||
user_properties: "User Properties"
|
checkbox: "Post Builder"
|
||||||
wizard_fields: "Wizard Fields"
|
label: "Builder"
|
||||||
wizard_actions: "Wizard Actions"
|
user_properties: "User Properties"
|
||||||
placeholder: "Insert wizard fields using the field_id in w{}. Insert user properties using property in u{}."
|
wizard_fields: "Wizard Fields"
|
||||||
add_to_group:
|
wizard_actions: "Wizard Actions"
|
||||||
label: "Add to Group"
|
placeholder: "Insert wizard fields using the field_id in w{}. Insert user properties using property in u{}."
|
||||||
route_to:
|
add_to_group:
|
||||||
label: "Route To"
|
label: "Add to Group"
|
||||||
url: "Url"
|
route_to:
|
||||||
code: "Code"
|
label: "Route To"
|
||||||
send_to_api:
|
url: "Url"
|
||||||
label: "Send to API"
|
code: "Code"
|
||||||
api: "API"
|
send_to_api:
|
||||||
endpoint: "Endpoint"
|
label: "Send to API"
|
||||||
select_an_api: "Select an API"
|
api: "API"
|
||||||
select_an_endpoint: "Select an endpoint"
|
endpoint: "Endpoint"
|
||||||
body: "Body"
|
select_an_api: "Select an API"
|
||||||
body_placeholder: "JSON"
|
select_an_endpoint: "Select an endpoint"
|
||||||
create_category:
|
body: "Body"
|
||||||
label: "Create Category"
|
body_placeholder: "JSON"
|
||||||
name: Name
|
create_category:
|
||||||
slug: Slug
|
label: "Create Category"
|
||||||
color: Color
|
name: Name
|
||||||
text_color: Text color
|
slug: Slug
|
||||||
parent_category: Parent Category
|
color: Color
|
||||||
permissions: Permissions
|
text_color: Text color
|
||||||
create_group:
|
parent_category: Parent Category
|
||||||
label: Create Group
|
permissions: Permissions
|
||||||
name: Name
|
create_group:
|
||||||
full_name: Full Name
|
label: Create Group
|
||||||
title: Title
|
name: Name
|
||||||
bio_raw: About
|
full_name: Full Name
|
||||||
owner_usernames: Owners
|
title: Title
|
||||||
usernames: Members
|
bio_raw: About
|
||||||
grant_trust_level: Automatic Trust Level
|
owner_usernames: Owners
|
||||||
mentionable_level: Mentionable Level
|
usernames: Members
|
||||||
messageable_level: Messageable Level
|
grant_trust_level: Automatic Trust Level
|
||||||
visibility_level: Visibility Level
|
mentionable_level: Mentionable Level
|
||||||
members_visibility_level: Members Visibility Level
|
messageable_level: Messageable Level
|
||||||
|
visibility_level: Visibility Level
|
||||||
|
members_visibility_level: Members Visibility Level
|
||||||
|
|
||||||
custom_field:
|
custom_field:
|
||||||
nav_label: "Custom Fields"
|
nav_label: "Custom Fields"
|
||||||
add: "Add"
|
add: "Add"
|
||||||
external:
|
external:
|
||||||
label: "from another plugin"
|
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."
|
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:
|
name:
|
||||||
|
@ -385,7 +386,7 @@ en:
|
||||||
basic_category: "Category"
|
basic_category: "Category"
|
||||||
basic_group: "Group"
|
basic_group: "Group"
|
||||||
post: "Post"
|
post: "Post"
|
||||||
|
|
||||||
submissions:
|
submissions:
|
||||||
nav_label: "Submissions"
|
nav_label: "Submissions"
|
||||||
title: "{{name}} Submissions"
|
title: "{{name}} Submissions"
|
||||||
|
@ -467,7 +468,7 @@ en:
|
||||||
|
|
||||||
subscription_container:
|
subscription_container:
|
||||||
title: Subscriber Features
|
title: Subscriber Features
|
||||||
subscribed:
|
subscribed:
|
||||||
label: Subscribed
|
label: Subscribed
|
||||||
title: You're subscribed and can use these features
|
title: You're subscribed and can use these features
|
||||||
not_subscribed:
|
not_subscribed:
|
||||||
|
@ -635,7 +636,7 @@ en:
|
||||||
yourself_confirm:
|
yourself_confirm:
|
||||||
title: "Did you forget to add recipients?"
|
title: "Did you forget to add recipients?"
|
||||||
body: "Right now this message is only being sent to yourself!"
|
body: "Right now this message is only being sent to yourself!"
|
||||||
|
|
||||||
realtime_validations:
|
realtime_validations:
|
||||||
similar_topics:
|
similar_topics:
|
||||||
insufficient_characters: "Type a minimum 5 characters to start looking for similar topics"
|
insufficient_characters: "Type a minimum 5 characters to start looking for similar topics"
|
||||||
|
|
|
@ -6,7 +6,7 @@ en:
|
||||||
|
|
||||||
wizard:
|
wizard:
|
||||||
custom_title: "Wizard"
|
custom_title: "Wizard"
|
||||||
|
|
||||||
custom_field:
|
custom_field:
|
||||||
error:
|
error:
|
||||||
required_attribute: "'%{attr}' is a required attribute"
|
required_attribute: "'%{attr}' is a required attribute"
|
||||||
|
@ -18,7 +18,7 @@ en:
|
||||||
name_already_taken: "'%{name}' is already taken as a custom field name"
|
name_already_taken: "'%{name}' is already taken as a custom field name"
|
||||||
save_default: "Failed to save custom field '%{name}'"
|
save_default: "Failed to save custom field '%{name}'"
|
||||||
subscription_type: "%{type} custom fields require a subscription"
|
subscription_type: "%{type} custom fields require a subscription"
|
||||||
|
|
||||||
field:
|
field:
|
||||||
too_short: "%{label} must be at least %{min} characters"
|
too_short: "%{label} must be at least %{min} characters"
|
||||||
too_long: "%{label} must not be more than %{max} characters"
|
too_long: "%{label} must not be more than %{max} characters"
|
||||||
|
@ -27,30 +27,30 @@ en:
|
||||||
invalid_file: "%{label} must be a %{types}"
|
invalid_file: "%{label} must be a %{types}"
|
||||||
invalid_date: "Invalid date"
|
invalid_date: "Invalid date"
|
||||||
invalid_time: "Invalid time"
|
invalid_time: "Invalid time"
|
||||||
|
|
||||||
none: "We couldn't find a wizard at that address."
|
none: "We couldn't find a wizard at that address."
|
||||||
no_skip: "Wizard can't be skipped"
|
no_skip: "Wizard can't be skipped"
|
||||||
export:
|
export:
|
||||||
error:
|
error:
|
||||||
select_one: "Please select at least one valid wizard"
|
select_one: "Please select at least one valid wizard"
|
||||||
invalid_wizards: "No valid wizards selected"
|
invalid_wizards: "No valid wizards selected"
|
||||||
|
|
||||||
import:
|
import:
|
||||||
error:
|
error:
|
||||||
no_file: "No file selected"
|
no_file: "No file selected"
|
||||||
file_large: "File too large"
|
file_large: "File too large"
|
||||||
invalid_json: "File is not a valid json file"
|
invalid_json: "File is not a valid json file"
|
||||||
|
|
||||||
destroy:
|
destroy:
|
||||||
error:
|
error:
|
||||||
no_template: No template found
|
no_template: No template found
|
||||||
default: Error destroying wizard
|
default: Error destroying wizard
|
||||||
|
|
||||||
validation:
|
validation:
|
||||||
required: "%{property} is required"
|
required: "%{attribute} is required"
|
||||||
conflict: "Wizard with id '%{wizard_id}' already exists"
|
conflict: "Wizard with id '%{wizard_id}' already exists"
|
||||||
after_time: "After time setting is invalid"
|
after_time: "After time setting is invalid"
|
||||||
subscription: "%{type} %{property} is subscription only"
|
subscription: "%{class} %{attribute} is subscription only"
|
||||||
|
|
||||||
notice:
|
notice:
|
||||||
connection_error: "Failed to connect to http://%{domain}"
|
connection_error: "Failed to connect to http://%{domain}"
|
||||||
|
@ -62,7 +62,7 @@ en:
|
||||||
title: Unable to connect to the Custom Wizard Plugin status server
|
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.
|
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:
|
subscription_message:
|
||||||
connection_error:
|
connection_error:
|
||||||
title: Unable to connect to the Custom Wizard Plugin subscription server
|
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.
|
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
|
next
|
||||||
end
|
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))
|
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class ::CustomWizard::CustomField
|
||||||
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
|
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
|
||||||
end
|
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))
|
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,11 @@ class CustomWizard::Subscription
|
||||||
@subscription.active?
|
@subscription.active?
|
||||||
end
|
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
|
def server
|
||||||
"test.thepavilion.io"
|
"test.thepavilion.io"
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,16 +5,34 @@ class CustomWizard::Subscription::Subscription
|
||||||
attr_reader :type,
|
attr_reader :type,
|
||||||
:updated_at
|
:updated_at
|
||||||
|
|
||||||
NONE ||= "none"
|
|
||||||
STANDARD ||= "standard"
|
STANDARD ||= "standard"
|
||||||
BUSINESS ||= "business"
|
BUSINESS ||= "business"
|
||||||
FEATURES ||= {
|
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: {
|
type: {
|
||||||
create_topic: NONE,
|
|
||||||
update_profile: NONE,
|
|
||||||
open_composer: NONE,
|
|
||||||
route_to: NONE,
|
|
||||||
send_message: STANDARD,
|
send_message: STANDARD,
|
||||||
watch_categories: STANDARD,
|
watch_categories: STANDARD,
|
||||||
add_to_group: STANDARD,
|
add_to_group: STANDARD,
|
||||||
|
@ -23,20 +41,16 @@ class CustomWizard::Subscription::Subscription
|
||||||
create_group: BUSINESS
|
create_group: BUSINESS
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
custom_fields: {
|
custom_field: {
|
||||||
klass: {
|
klass: {
|
||||||
topic: NONE,
|
|
||||||
post: NONE,
|
|
||||||
group: BUSINESS,
|
group: BUSINESS,
|
||||||
category: BUSINESS
|
category: BUSINESS
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
string: NONE,
|
|
||||||
boolean: NONE,
|
|
||||||
integer: NONE,
|
|
||||||
json: STANDARD
|
json: STANDARD
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
api: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize(subscription)
|
def initialize(subscription)
|
||||||
|
@ -47,23 +61,33 @@ class CustomWizard::Subscription::Subscription
|
||||||
end
|
end
|
||||||
|
|
||||||
def active?
|
def active?
|
||||||
types.include?(type) && updated_at.to_datetime > (Time.zone.now - 2.hours).to_datetime
|
self.class.types.include?(type) && updated_recently
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_use_feature?(feature, attribute, value)
|
def updated_recently
|
||||||
feature_type = FEATURES.dig(*[feature.to_sym, attribute.to_sym, value.to_sym])
|
updated_at.to_datetime > (Time.zone.now - 2.hours).to_datetime
|
||||||
!feature_type || has_required_type?(feature_type)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_required_type?(t)
|
def has_required_type?(t)
|
||||||
t && type_index(t) >= type_index(type)
|
t && type && type_index(type) >= type_index(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_index(t)
|
def type_index(t)
|
||||||
self.class.types.index(t)
|
self.class.types.index(t)
|
||||||
end
|
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
|
def self.types
|
||||||
[NONE, STANDARD, BUSINESS]
|
[STANDARD, BUSINESS]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,34 +13,26 @@ class CustomWizard::TemplateValidator
|
||||||
data = @data
|
data = @data
|
||||||
|
|
||||||
check_id(data, :wizard)
|
check_id(data, :wizard)
|
||||||
check_required(data, :wizard)
|
|
||||||
validate_after_time
|
validate_after_time
|
||||||
validate_subscription(data, :wizard)
|
validate_class(data, :wizard)
|
||||||
|
|
||||||
data[:steps].each do |step|
|
data[:steps].each do |step|
|
||||||
check_required(step, :step)
|
validate_class(step, :step)
|
||||||
validate_subscription(step, :step)
|
|
||||||
|
|
||||||
if step[:fields].present?
|
if step[:fields].present?
|
||||||
step[:fields].each do |field|
|
step[:fields].each do |field|
|
||||||
validate_subscription(field, :field)
|
validate_class(field, :field)
|
||||||
check_required(field, :field)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if data[:actions].present?
|
if data[:actions].present?
|
||||||
data[:actions].each do |action|
|
data[:actions].each do |action|
|
||||||
validate_subscription(action, :action)
|
validate_class(action, :action)
|
||||||
check_required(action, :action)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if errors.any?
|
!errors.any?
|
||||||
false
|
|
||||||
else
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.required
|
def self.required
|
||||||
|
@ -52,56 +44,25 @@ class CustomWizard::TemplateValidator
|
||||||
}
|
}
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def check_required(object, type)
|
def validate_class(object, klass)
|
||||||
self.class.required[type].each do |property|
|
check_required(object, klass)
|
||||||
if object[property].blank?
|
validate_subscription(object, klass)
|
||||||
errors.add :base, I18n.t("wizard.validation.required", property: property)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_subscription(object, type)
|
def validate_subscription(object, klass)
|
||||||
self.class.subscription[type].each do |property, subscription_type|
|
object.keys.each do |attribute|
|
||||||
val = object[property.to_s]
|
if !@subscription.can_use_feature?(klass, attribute, object[attribute])
|
||||||
is_subscription = (val != nil) && (
|
errors.add :base, I18n.t("wizard.validation.subscription", class: klass.to_s, attribute: attribute)
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,7 @@ describe CustomWizard::Action do
|
||||||
let(:create_group) { get_wizard_fixture("actions/create_group") }
|
let(:create_group) { get_wizard_fixture("actions/create_group") }
|
||||||
let(:add_to_group) { get_wizard_fixture("actions/add_to_group") }
|
let(:add_to_group) { get_wizard_fixture("actions/add_to_group") }
|
||||||
let(:send_message) { get_wizard_fixture("actions/send_message") }
|
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(:send_message_multi) { get_wizard_fixture("actions/send_message_multi") }
|
||||||
let(:api_test_endpoint) { get_wizard_fixture("endpoints/test_endpoint") }
|
let(:api_test_endpoint) { get_wizard_fixture("endpoints/test_endpoint") }
|
||||||
let(:api_test_endpoint_body) { get_wizard_fixture("endpoints/test_endpoint_body") }
|
let(:api_test_endpoint_body) { get_wizard_fixture("endpoints/test_endpoint_body") }
|
||||||
|
@ -159,17 +160,6 @@ describe CustomWizard::Action do
|
||||||
end
|
end
|
||||||
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
|
it 're-routes a user' do
|
||||||
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||||
updater = wizard.create_updater(wizard.steps.last.id, {})
|
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")
|
expect(updater.result[:redirect_on_next]).to eq("https://google.com")
|
||||||
end
|
end
|
||||||
|
|
||||||
context "subscription actions" do
|
context "standard subscription actions" do
|
||||||
before do
|
before do
|
||||||
enable_subscription("standard")
|
enable_subscription("standard")
|
||||||
end
|
end
|
||||||
|
@ -235,6 +225,38 @@ describe CustomWizard::Action do
|
||||||
expect(post.exists?).to eq(true)
|
expect(post.exists?).to eq(true)
|
||||||
end
|
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
|
it '#create_category' do
|
||||||
wizard_template['actions'] << create_category
|
wizard_template['actions'] << create_category
|
||||||
update_template(wizard_template)
|
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)
|
expect(Group.where(name: wizard.current_submission.fields['action_9']).exists?).to eq(true)
|
||||||
end
|
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
|
it '#send_to_api successful' do
|
||||||
stub_request(:put, "https://myexternalapi.com/update").
|
stub_request(:put, "https://myexternalapi.com/update").
|
||||||
with(
|
with(
|
||||||
|
|
|
@ -20,6 +20,7 @@ describe CustomWizard::Builder do
|
||||||
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
|
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
|
||||||
let(:permitted_param_json) { get_wizard_fixture("step/permitted_params") }
|
let(:permitted_param_json) { get_wizard_fixture("step/permitted_params") }
|
||||||
let(:user_condition_json) { get_wizard_fixture("condition/user_condition") }
|
let(:user_condition_json) { get_wizard_fixture("condition/user_condition") }
|
||||||
|
let(:prefill_json) { get_wizard_fixture("field/prefill") }
|
||||||
|
|
||||||
let(:boolean_field_condition_json) {
|
let(:boolean_field_condition_json) {
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
|
@ -35,6 +36,12 @@ describe CustomWizard::Builder do
|
||||||
@template = CustomWizard::Template.find('super_mega_fun_wizard')
|
@template = CustomWizard::Template.find('super_mega_fun_wizard')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def perform_update(step_id, submission)
|
||||||
|
updater = @wizard.create_updater(step_id, submission)
|
||||||
|
updater.update
|
||||||
|
updater
|
||||||
|
end
|
||||||
|
|
||||||
context 'disabled' do
|
context 'disabled' do
|
||||||
before do
|
before do
|
||||||
SiteSetting.custom_wizard_enabled = false
|
SiteSetting.custom_wizard_enabled = false
|
||||||
|
@ -101,6 +108,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context "with restricted permissions" do
|
context "with restricted permissions" do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription("standard")
|
||||||
@template[:permitted] = permitted_json["permitted"]
|
@template[:permitted] = permitted_json["permitted"]
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
@ -155,13 +163,21 @@ describe CustomWizard::Builder do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns prefilled data' do
|
context "prefilled data" do
|
||||||
expect(
|
before do
|
||||||
CustomWizard::Builder.new(@template[:id], user).build
|
enable_subscription("standard")
|
||||||
.steps.first
|
@template[:steps][0][:fields][0][:prefill] = prefill_json["prefill"]
|
||||||
.fields.first
|
CustomWizard::Template.save(@template.as_json)
|
||||||
.value
|
end
|
||||||
).to eq('I am prefilled')
|
|
||||||
|
it "works" do
|
||||||
|
expect(
|
||||||
|
CustomWizard::Builder.new(@template[:id], user).build
|
||||||
|
.steps.first
|
||||||
|
.fields.first
|
||||||
|
.value
|
||||||
|
).to eq('I am prefilled')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "user has partially completed" do
|
context "user has partially completed" do
|
||||||
|
@ -190,12 +206,14 @@ describe CustomWizard::Builder do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not return saved submissions' do
|
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(
|
expect(
|
||||||
CustomWizard::Builder.new(@template[:id], user).build
|
CustomWizard::Builder.new(@template[:id], user).build
|
||||||
.steps.first
|
.steps.first
|
||||||
.fields.first
|
.fields.first
|
||||||
.value
|
.value
|
||||||
).to eq('I am prefilled')
|
).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -213,7 +231,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context 'with required data' do
|
context 'with required data' do
|
||||||
before do
|
before do
|
||||||
enable_subscription("standard")
|
enable_subscription("business")
|
||||||
@template[:steps][0][:required_data] = required_data_json['required_data']
|
@template[:steps][0][:required_data] = required_data_json['required_data']
|
||||||
@template[:steps][0][:required_data_message] = required_data_json['required_data_message']
|
@template[:steps][0][:required_data_message] = required_data_json['required_data_message']
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
|
@ -249,7 +267,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context "with permitted params" do
|
context "with permitted params" do
|
||||||
before do
|
before do
|
||||||
enable_subscription("standard")
|
enable_subscription("business")
|
||||||
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
|
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
@ -298,14 +316,14 @@ describe CustomWizard::Builder do
|
||||||
.build
|
.build
|
||||||
.steps.first
|
.steps.first
|
||||||
.fields.length
|
.fields.length
|
||||||
).to eq(4)
|
).to eq(3)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with condition" do
|
context "with condition" do
|
||||||
before do
|
before do
|
||||||
enable_subscription("standard")
|
enable_subscription("standard")
|
||||||
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
|
@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)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -326,18 +344,12 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
builder = CustomWizard::Builder.new(@template[:id], user)
|
builder = CustomWizard::Builder.new(@template[:id], user)
|
||||||
wizard = builder.build
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'on update' do
|
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
|
it 'saves submissions' do
|
||||||
@wizard = CustomWizard::Builder.new(@template[:id], user).build
|
@wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||||
perform_update('step_1', step_1_field_1: 'Text input')
|
perform_update('step_1', step_1_field_1: 'Text input')
|
||||||
|
|
|
@ -48,6 +48,8 @@ describe CustomWizard::Template do
|
||||||
|
|
||||||
context "wizard template list" do
|
context "wizard template list" do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription("standard")
|
||||||
|
|
||||||
template_json_2 = template_json.dup
|
template_json_2 = template_json.dup
|
||||||
template_json_2["id"] = 'super_mega_fun_wizard_2'
|
template_json_2["id"] = 'super_mega_fun_wizard_2'
|
||||||
template_json_2["permitted"] = permitted_json['permitted']
|
template_json_2["permitted"] = permitted_json['permitted']
|
||||||
|
|
|
@ -6,6 +6,7 @@ describe CustomWizard::TemplateValidator do
|
||||||
let(:template) { get_wizard_fixture("wizard") }
|
let(:template) { get_wizard_fixture("wizard") }
|
||||||
let(:create_category) { get_wizard_fixture("actions/create_category") }
|
let(:create_category) { get_wizard_fixture("actions/create_category") }
|
||||||
let(:user_condition) { get_wizard_fixture("condition/user_condition") }
|
let(:user_condition) { get_wizard_fixture("condition/user_condition") }
|
||||||
|
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
|
||||||
|
|
||||||
it "validates valid templates" do
|
it "validates valid templates" do
|
||||||
expect(
|
expect(
|
||||||
|
@ -45,7 +46,7 @@ describe CustomWizard::TemplateValidator do
|
||||||
|
|
||||||
context "without subscription" do
|
context "without subscription" do
|
||||||
it "invalidates subscription wizard attributes" do
|
it "invalidates subscription wizard attributes" do
|
||||||
template[:save_submissions] = false
|
template[:permitted] = permitted_json["permitted"]
|
||||||
expect(
|
expect(
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
).to eq(false)
|
).to eq(false)
|
||||||
|
@ -73,13 +74,13 @@ describe CustomWizard::TemplateValidator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with subscription" do
|
context "with standard subscription" do
|
||||||
before do
|
before do
|
||||||
enable_subscription("standard")
|
enable_subscription("standard")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates wizard attributes" do
|
it "validates wizard attributes" do
|
||||||
template[:save_submissions] = false
|
template[:permitted] = permitted_json["permitted"]
|
||||||
expect(
|
expect(
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
).to eq(true)
|
).to eq(true)
|
||||||
|
@ -98,6 +99,12 @@ describe CustomWizard::TemplateValidator do
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
).to eq(true)
|
).to eq(true)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with business subscription" do
|
||||||
|
before do
|
||||||
|
enable_subscription("business")
|
||||||
|
end
|
||||||
|
|
||||||
it "validates actions" do
|
it "validates actions" do
|
||||||
template[:actions] << create_category
|
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][0][:min_length] = min_length
|
||||||
@template[:steps][0][:fields][1][: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)
|
CustomWizard::Template.save(@template)
|
||||||
|
|
||||||
|
@ -35,11 +34,6 @@ describe CustomWizard::UpdateValidator do
|
||||||
expect(
|
expect(
|
||||||
updater.errors.messages[:step_1_field_2].first
|
updater.errors.messages[:step_1_field_2].first
|
||||||
).to eq(I18n.t('wizard.field.too_short', label: 'Textarea', min: min_length))
|
).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
|
end
|
||||||
|
|
||||||
it 'prevents submission if the length is over the max length' do
|
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][0][:max_length] = max_length
|
||||||
@template[:steps][0][:fields][1][: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)
|
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. "
|
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(
|
expect(
|
||||||
updater.errors.messages[:step_1_field_2].first
|
updater.errors.messages[:step_1_field_2].first
|
||||||
).to eq(I18n.t('wizard.field.too_long', label: 'Textarea', max: max_length))
|
).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
|
end
|
||||||
|
|
||||||
it "allows submission if the length is under or equal to the max length" do
|
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][0][:max_length] = max_length
|
||||||
@template[:steps][0][:fields][1][: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)
|
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."
|
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(
|
expect(
|
||||||
updater.errors.messages[:step_1_field_2].first
|
updater.errors.messages[:step_1_field_2].first
|
||||||
).to eq(nil)
|
).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
|
end
|
||||||
|
|
||||||
it "applies min length only if the input is non-empty" do
|
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 = template_json.dup
|
||||||
@permitted_template["permitted"] = permitted_json["permitted"]
|
@permitted_template["permitted"] = permitted_json["permitted"]
|
||||||
@wizard = CustomWizard::Wizard.new(template_json, user)
|
@wizard = CustomWizard::Wizard.new(template_json, user)
|
||||||
|
enable_subscription("standard")
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_steps
|
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": [
|
"group": [
|
||||||
{
|
{
|
||||||
"type": "assignment",
|
"type": "assignment",
|
||||||
"output": "action_9",
|
"output": "",
|
||||||
"output_type": "wizard_action",
|
"output_type": "text",
|
||||||
"output_connector": "set"
|
"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",
|
"label": "Text",
|
||||||
"description": "Text field description.",
|
"description": "Text field description.",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"min_length": "3",
|
"min_length": "3"
|
||||||
"prefill": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "I am prefilled",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "step_1_field_2",
|
"id": "step_1_field_2",
|
||||||
|
@ -33,11 +25,6 @@
|
||||||
"type": "textarea",
|
"type": "textarea",
|
||||||
"min_length": ""
|
"min_length": ""
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "step_1_field_3",
|
|
||||||
"label": "Composer",
|
|
||||||
"type": "composer"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "step_1_field_4",
|
"id": "step_1_field_4",
|
||||||
"label": "I'm only text",
|
"label": "I'm only text",
|
||||||
|
@ -102,55 +89,7 @@
|
||||||
{
|
{
|
||||||
"id": "step_3_field_1",
|
"id": "step_3_field_1",
|
||||||
"label": "Custom Dropdown",
|
"label": "Custom Dropdown",
|
||||||
"type": "dropdown",
|
"type": "dropdown"
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"type": "association",
|
|
||||||
"pairs": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"key": "choice1",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Choice 1",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "equal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 1,
|
|
||||||
"key": "choice2",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Choice 2",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 2,
|
|
||||||
"key": "choice3",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Choice 3",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_2",
|
|
||||||
"label": "Tag",
|
|
||||||
"type": "tag"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_3",
|
|
||||||
"label": "Category",
|
|
||||||
"type": "category",
|
|
||||||
"limit": 1,
|
|
||||||
"property": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_4",
|
|
||||||
"label": "Group",
|
|
||||||
"type": "group"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "step_3_field_5",
|
"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",
|
"id": "action_4",
|
||||||
"run_after": "step_2",
|
"run_after": "step_2",
|
||||||
|
@ -337,4 +253,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ def enable_subscription(type)
|
||||||
# CustomWizard::Subscription.new
|
# CustomWizard::Subscription.new
|
||||||
CustomWizard::Subscription.any_instance.stubs(:subscribed?).returns(true)
|
CustomWizard::Subscription.any_instance.stubs(:subscribed?).returns(true)
|
||||||
CustomWizard::Subscription.any_instance.stubs(:type).returns(type)
|
CustomWizard::Subscription.any_instance.stubs(:type).returns(type)
|
||||||
|
CustomWizard::Subscription::Subscription.any_instance.stubs(:type).returns(type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def disable_subscription
|
def disable_subscription
|
||||||
|
|
|
@ -8,6 +8,7 @@ describe CustomWizard::AdminWizardController do
|
||||||
let(:template) { get_wizard_fixture("wizard") }
|
let(:template) { get_wizard_fixture("wizard") }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
enable_subscription("standard")
|
||||||
CustomWizard::Template.save(template, skip_jobs: true)
|
CustomWizard::Template.save(template, skip_jobs: true)
|
||||||
|
|
||||||
template_2 = template.dup
|
template_2 = template.dup
|
||||||
|
|
|
@ -35,6 +35,8 @@ describe CustomWizard::StepsController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "when the user cant access the wizard" do
|
it "when the user cant access the wizard" do
|
||||||
|
enable_subscription("standard")
|
||||||
|
|
||||||
new_template = wizard_template.dup
|
new_template = wizard_template.dup
|
||||||
new_template["permitted"] = permitted_json["permitted"]
|
new_template["permitted"] = permitted_json["permitted"]
|
||||||
CustomWizard::Template.save(new_template, skip_jobs: true)
|
CustomWizard::Template.save(new_template, skip_jobs: true)
|
||||||
|
|
|
@ -18,10 +18,10 @@ describe CustomWizard::FieldSerializer do
|
||||||
scope: Guardian.new(user)
|
scope: Guardian.new(user)
|
||||||
).as_json
|
).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][:label]).to eq("<p>Text</p>")
|
||||||
expect(json_array[0][:description]).to eq("Text field description.")
|
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
|
end
|
||||||
|
|
||||||
it "should return optional field attributes" do
|
it "should return optional field attributes" do
|
||||||
|
|
|
@ -42,55 +42,73 @@ describe CustomWizard::WizardSerializer do
|
||||||
).to eq(BasicUserSerializer.new(user, root: false).as_json)
|
).to eq(BasicUserSerializer.new(user, root: false).as_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not return categories if there are no category fields" do
|
context "with subscription" do
|
||||||
@template[:steps][2][:fields].delete_at(2)
|
before do
|
||||||
CustomWizard::Template.save(@template)
|
enable_subscription("standard")
|
||||||
|
end
|
||||||
|
|
||||||
json = CustomWizard::WizardSerializer.new(
|
it "should not return categories if there are no category fields" do
|
||||||
CustomWizard::Builder.new(@template[:id], user).build,
|
@template[:steps][2][:fields].delete_at(2)
|
||||||
scope: Guardian.new(user)
|
CustomWizard::Template.save(@template)
|
||||||
).as_json
|
|
||||||
expect(json[:wizard][:categories].present?).to eq(false)
|
|
||||||
expect(json[:wizard][:uncategorized_category_id].present?).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should return categories if there is a category selector field" do
|
json = CustomWizard::WizardSerializer.new(
|
||||||
json = CustomWizard::WizardSerializer.new(
|
CustomWizard::Builder.new(@template[:id], user).build,
|
||||||
CustomWizard::Builder.new(@template[:id], user).build,
|
scope: Guardian.new(user)
|
||||||
scope: Guardian.new(user)
|
).as_json
|
||||||
).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 similar topics validation scoped to category(s)" do
|
expect(json[:wizard][:categories].present?).to eq(false)
|
||||||
@template[:steps][0][:fields][0][:validations] = similar_topics_validation[:validations]
|
expect(json[:wizard][:uncategorized_category_id].present?).to eq(false)
|
||||||
CustomWizard::Template.save(@template)
|
end
|
||||||
|
|
||||||
json = CustomWizard::WizardSerializer.new(
|
it "should return categories if there is a category selector field" do
|
||||||
CustomWizard::Builder.new(@template[:id], user).build,
|
@template[:steps][0][:fields] << { "id": "step_1_field_5", "label": "Category", "type": "category" }.as_json
|
||||||
scope: Guardian.new(user)
|
CustomWizard::Template.save(@template)
|
||||||
).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
|
json = CustomWizard::WizardSerializer.new(
|
||||||
json = CustomWizard::WizardSerializer.new(
|
CustomWizard::Builder.new(@template[:id], user).build,
|
||||||
CustomWizard::Builder.new(@template[:id], user).build,
|
scope: Guardian.new(user)
|
||||||
scope: Guardian.new(user)
|
).as_json
|
||||||
).as_json
|
|
||||||
expect(json[:wizard][:groups].length).to eq(8)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should not return groups if there is not a group selector field' do
|
expect(json[:wizard][:categories].present?).to eq(true)
|
||||||
@template[:steps][2][:fields].delete_at(3)
|
expect(json[:wizard][:uncategorized_category_id].present?).to eq(true)
|
||||||
CustomWizard::Template.save(@template)
|
end
|
||||||
|
|
||||||
json = CustomWizard::WizardSerializer.new(
|
it "should return categories if there is a similar topics validation scoped to category(s)" do
|
||||||
CustomWizard::Builder.new(@template[:id], user).build,
|
@template[:steps][0][:fields][0][:validations] = similar_topics_validation
|
||||||
scope: Guardian.new(user)
|
CustomWizard::Template.save(@template)
|
||||||
).as_json
|
|
||||||
expect(json[:wizard][:groups].present?).to eq(false)
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,12 +29,12 @@ describe CustomWizard::StepSerializer do
|
||||||
each_serializer: described_class,
|
each_serializer: described_class,
|
||||||
scope: Guardian.new(user)
|
scope: Guardian.new(user)
|
||||||
).as_json
|
).as_json
|
||||||
expect(json_array[0][:fields].length).to eq(4)
|
expect(json_array[0][:fields].length).to eq(3)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with required data' do
|
context 'with required data' do
|
||||||
before 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'] = required_data_json['required_data']
|
||||||
wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message']
|
wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message']
|
||||||
CustomWizard::Template.save(wizard_template)
|
CustomWizard::Template.save(wizard_template)
|
||||||
|
|
Laden …
In neuem Issue referenzieren