From d351577ea39d64bea565a428b59384f0fd4f3d96 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 15 Feb 2022 12:33:04 +1100 Subject: [PATCH] Update subscription, tests and type handling --- .../components/custom-field-input.js.es6 | 6 +- .../components/wizard-custom-action.js.es6 | 4 +- .../initializers/custom-wizard-edits.js.es6 | 2 +- .../discourse/lib/wizard-schema.js.es6 | 29 ++- .../javascripts/discourse/lib/wizard.js.es6 | 24 +-- .../routes/admin-wizards-wizard.js.es6 | 2 +- .../templates/admin-wizards-wizard-show.hbs | 72 +++---- .../components/wizard-custom-field.hbs | 13 +- .../components/wizard-custom-step.hbs | 3 +- assets/stylesheets/admin/admin.scss | 1 + config/locales/client.en.yml | 175 +++++++++--------- config/locales/server.en.yml | 18 +- lib/custom_wizard/custom_field.rb | 4 +- lib/custom_wizard/subscription.rb | 5 + .../subscription/subscription.rb | 62 +++++-- lib/custom_wizard/validators/template.rb | 75 ++------ spec/components/custom_wizard/action_spec.rb | 59 +++--- spec/components/custom_wizard/builder_spec.rb | 50 +++-- .../components/custom_wizard/template_spec.rb | 2 + .../custom_wizard/template_validator_spec.rb | 13 +- .../custom_wizard/update_validator_spec.rb | 18 -- spec/components/custom_wizard/wizard_spec.rb | 1 + spec/fixtures/actions/add_to_group.json | 6 +- spec/fixtures/actions/watch_categories.json | 23 +++ spec/fixtures/field/content.json | 33 ++++ spec/fixtures/field/prefill.json | 10 + spec/fixtures/wizard.json | 90 +-------- spec/plugin_helper.rb | 1 + .../admin/wizard_controller_spec.rb | 1 + .../custom_wizard/steps_controller_spec.rb | 2 + .../wizard_field_serializer_spec.rb | 4 +- .../custom_wizard/wizard_serializer_spec.rb | 104 ++++++----- .../wizard_step_serializer_spec.rb | 4 +- 33 files changed, 467 insertions(+), 449 deletions(-) create mode 100644 spec/fixtures/actions/watch_categories.json create mode 100644 spec/fixtures/field/content.json create mode 100644 spec/fixtures/field/prefill.json diff --git a/assets/javascripts/discourse/components/custom-field-input.js.es6 b/assets/javascripts/discourse/components/custom-field-input.js.es6 index fa7f0c0c..9f739eba 100644 --- a/assets/javascripts/discourse/components/custom-field-input.js.es6 +++ b/assets/javascripts/discourse/components/custom-field-input.js.es6 @@ -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") diff --git a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 index 233a8087..7d17b62b 100644 --- a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 @@ -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); }, }); diff --git a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 index 035fa6f2..6a027dee 100644 --- a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 +++ b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 @@ -64,7 +64,7 @@ export default { this.set("customWizardCriticalNotices", criticalNotices); } }); - } + }, }); api.modifyClass("component:d-navigation", { diff --git a/assets/javascripts/discourse/lib/wizard-schema.js.es6 b/assets/javascripts/discourse/lib/wizard-schema.js.es6 index 2ef99857..ec8f81c4 100644 --- a/assets/javascripts/discourse/lib/wizard-schema.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-schema.js.es6 @@ -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; diff --git a/assets/javascripts/discourse/lib/wizard.js.es6 b/assets/javascripts/discourse/lib/wizard.js.es6 index 1d009d36..34991029 100644 --- a/assets/javascripts/discourse/lib/wizard.js.es6 +++ b/assets/javascripts/discourse/lib/wizard.js.es6 @@ -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, }; diff --git a/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 index 8977b3d0..33822b05 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 @@ -11,7 +11,7 @@ export default DiscourseRoute.extend({ }, afterModel(model) { - buildSchema(model) + buildSchema(model); return all([ this._getThemes(model), diff --git a/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs b/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs index abf06ba9..0886c519 100644 --- a/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs +++ b/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs @@ -53,16 +53,6 @@
-
-
- -
-
- {{input type="checkbox" checked=wizard.required}} - {{i18n "admin.wizard.required_label"}} -
-
-
@@ -83,6 +73,26 @@
+
+
+ +
+
+ {{input type="checkbox" checked=wizard.save_submissions}} + {{i18n "admin.wizard.save_submissions_label"}} +
+
+ +
+
+ +
+
+ {{input type="checkbox" checked=wizard.restart_on_revisit}} + {{i18n "admin.wizard.restart_on_revisit_label"}} +
+
+
@@ -93,7 +103,7 @@
-
+
@@ -108,42 +118,32 @@
-
-
- -
-
- {{wizard-mapper - inputs=wizard.permitted - options=(hash - context="wizard" - inputTypes="assignment,validation" - groupSelection="output" - userFieldSelection="key" - textSelection="value" - inputConnector="and" - )}} -
-
- {{#subscription-container subscribed=subscribed}}
- +
- {{input type="checkbox" checked=wizard.save_submissions}} - {{i18n "admin.wizard.save_submissions_label"}} + {{input type="checkbox" checked=wizard.required}} + {{i18n "admin.wizard.required_label"}}
-
+
- +
- {{input type="checkbox" checked=wizard.restart_on_revisit}} - {{i18n "admin.wizard.restart_on_revisit_label"}} + {{wizard-mapper + inputs=wizard.permitted + options=(hash + context="wizard" + inputTypes="assignment,validation" + groupSelection="output" + userFieldSelection="key" + textSelection="value" + inputConnector="and" + )}}
{{/subscription-container}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index 0802d772..4790bb8b 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -19,7 +19,7 @@
- +
{{i18n "admin.wizard.field.required_label"}} {{input type="checkbox" checked=field.required}} @@ -54,7 +54,7 @@
- +
{{combo-box value=field.type @@ -220,10 +220,10 @@ options=fieldConditionOptions}}
- +
- > +
@@ -234,12 +234,11 @@
{{#if isCategory}} -
+
- {{i18n "admin.wizard.pro.label"}}
- +
{{combo-box value=field.property diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs index 0d1294f3..e05baa60 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs @@ -56,10 +56,9 @@
-
+
- {{i18n "admin.wizard.pro.label"}}
{{wizard-mapper diff --git a/assets/stylesheets/admin/admin.scss b/assets/stylesheets/admin/admin.scss index c026263a..557c25b2 100644 --- a/assets/stylesheets/admin/admin.scss +++ b/assets/stylesheets/admin/admin.scss @@ -920,6 +920,7 @@ $error: #ef1700; &:not(.subscribed) .subscription-settings { filter: blur(1px); + pointer-events: none; } } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 070bd594..613cd39f 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -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: "Moment.js format" 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" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 5c25690b..a95ce197 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -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 support@thepavilion.io 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 support@thepavilion.io for further assistance. diff --git a/lib/custom_wizard/custom_field.rb b/lib/custom_wizard/custom_field.rb index a24b1a06..ae724f80 100644 --- a/lib/custom_wizard/custom_field.rb +++ b/lib/custom_wizard/custom_field.rb @@ -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 diff --git a/lib/custom_wizard/subscription.rb b/lib/custom_wizard/subscription.rb index 6c535602..e3d4c971 100644 --- a/lib/custom_wizard/subscription.rb +++ b/lib/custom_wizard/subscription.rb @@ -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 diff --git a/lib/custom_wizard/subscription/subscription.rb b/lib/custom_wizard/subscription/subscription.rb index b195b59d..701485ec 100644 --- a/lib/custom_wizard/subscription/subscription.rb +++ b/lib/custom_wizard/subscription/subscription.rb @@ -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 diff --git a/lib/custom_wizard/validators/template.rb b/lib/custom_wizard/validators/template.rb index 4928c4e5..3c69f863 100644 --- a/lib/custom_wizard/validators/template.rb +++ b/lib/custom_wizard/validators/template.rb @@ -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 diff --git a/spec/components/custom_wizard/action_spec.rb b/spec/components/custom_wizard/action_spec.rb index 284f63d3..285813c0 100644 --- a/spec/components/custom_wizard/action_spec.rb +++ b/spec/components/custom_wizard/action_spec.rb @@ -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( diff --git a/spec/components/custom_wizard/builder_spec.rb b/spec/components/custom_wizard/builder_spec.rb index bb3ccf17..986cc20d 100644 --- a/spec/components/custom_wizard/builder_spec.rb +++ b/spec/components/custom_wizard/builder_spec.rb @@ -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') diff --git a/spec/components/custom_wizard/template_spec.rb b/spec/components/custom_wizard/template_spec.rb index fca7f91e..44f93bb4 100644 --- a/spec/components/custom_wizard/template_spec.rb +++ b/spec/components/custom_wizard/template_spec.rb @@ -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'] diff --git a/spec/components/custom_wizard/template_validator_spec.rb b/spec/components/custom_wizard/template_validator_spec.rb index 8cbe7956..94e11dce 100644 --- a/spec/components/custom_wizard/template_validator_spec.rb +++ b/spec/components/custom_wizard/template_validator_spec.rb @@ -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 diff --git a/spec/components/custom_wizard/update_validator_spec.rb b/spec/components/custom_wizard/update_validator_spec.rb index c79a5b0b..3278d208 100644 --- a/spec/components/custom_wizard/update_validator_spec.rb +++ b/spec/components/custom_wizard/update_validator_spec.rb @@ -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 diff --git a/spec/components/custom_wizard/wizard_spec.rb b/spec/components/custom_wizard/wizard_spec.rb index 8ee19c33..211cf5b5 100644 --- a/spec/components/custom_wizard/wizard_spec.rb +++ b/spec/components/custom_wizard/wizard_spec.rb @@ -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 diff --git a/spec/fixtures/actions/add_to_group.json b/spec/fixtures/actions/add_to_group.json index 2a5af1c3..b069edc4 100644 --- a/spec/fixtures/actions/add_to_group.json +++ b/spec/fixtures/actions/add_to_group.json @@ -5,9 +5,9 @@ "group": [ { "type": "assignment", - "output": "action_9", - "output_type": "wizard_action", + "output": "", + "output_type": "text", "output_connector": "set" } ] -} \ No newline at end of file +} diff --git a/spec/fixtures/actions/watch_categories.json b/spec/fixtures/actions/watch_categories.json new file mode 100644 index 00000000..ce805288 --- /dev/null +++ b/spec/fixtures/actions/watch_categories.json @@ -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" + } + ] +} diff --git a/spec/fixtures/field/content.json b/spec/fixtures/field/content.json new file mode 100644 index 00000000..f013aab6 --- /dev/null +++ b/spec/fixtures/field/content.json @@ -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" + } + ] + } + ] +} diff --git a/spec/fixtures/field/prefill.json b/spec/fixtures/field/prefill.json new file mode 100644 index 00000000..d79190b4 --- /dev/null +++ b/spec/fixtures/field/prefill.json @@ -0,0 +1,10 @@ +{ + "prefill": [ + { + "type": "assignment", + "output": "I am prefilled", + "output_type": "text", + "output_connector": "set" + } + ] +} diff --git a/spec/fixtures/wizard.json b/spec/fixtures/wizard.json index ad3b6d1b..7416bfb2 100644 --- a/spec/fixtures/wizard.json +++ b/spec/fixtures/wizard.json @@ -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 @@ ] } ] -} \ No newline at end of file +} diff --git a/spec/plugin_helper.rb b/spec/plugin_helper.rb index 232a2411..099030c7 100644 --- a/spec/plugin_helper.rb +++ b/spec/plugin_helper.rb @@ -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 diff --git a/spec/requests/custom_wizard/admin/wizard_controller_spec.rb b/spec/requests/custom_wizard/admin/wizard_controller_spec.rb index 9d7ed18d..ab0d5925 100644 --- a/spec/requests/custom_wizard/admin/wizard_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/wizard_controller_spec.rb @@ -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 diff --git a/spec/requests/custom_wizard/steps_controller_spec.rb b/spec/requests/custom_wizard/steps_controller_spec.rb index b55de419..8cdc0820 100644 --- a/spec/requests/custom_wizard/steps_controller_spec.rb +++ b/spec/requests/custom_wizard/steps_controller_spec.rb @@ -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) diff --git a/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb index 349b21f8..cf09ec6a 100644 --- a/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb @@ -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("

Text

") 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 diff --git a/spec/serializers/custom_wizard/wizard_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_serializer_spec.rb index fe36d5a2..6136ffe0 100644 --- a/spec/serializers/custom_wizard/wizard_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_serializer_spec.rb @@ -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 diff --git a/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb index f0128765..57ef8ae3 100644 --- a/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb @@ -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)