diff --git a/app/controllers/custom_wizard/wizard.rb b/app/controllers/custom_wizard/wizard.rb index bc0a06af..bb53670b 100644 --- a/app/controllers/custom_wizard/wizard.rb +++ b/app/controllers/custom_wizard/wizard.rb @@ -44,7 +44,7 @@ class CustomWizard::WizardController < ::ActionController::Base return render json: { error: I18n.t('wizard.no_skip') } end - result = success_json + result = { success: 'OK' } if current_user && wizard.can_access? if redirect_to = wizard.current_submission&.redirect_to diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 2483503b..08cf5336 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -53,6 +53,7 @@ en: after_signup_after_time: "You can't use 'after time' and 'after signup' on the same wizard." after_time: "After time setting is invalid." liquid_syntax_error: "Liquid syntax error in %{attribute}: %{message}" + subscription: "%{type} %{property} is subscription only" site_settings: custom_wizard_enabled: "Enable custom wizards." diff --git a/lib/custom_wizard/custom_field.rb b/lib/custom_wizard/custom_field.rb index f26c11fa..29423ec6 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.includes?(:custom_field, :klass, value) + if attr == 'klass' && !@subscription.includes?(: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.includes?(:custom_field, :type, value) + if attr == 'type' && !@subscription.includes?(: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 3d2d665e..114f6743 100644 --- a/lib/custom_wizard/subscription.rb +++ b/lib/custom_wizard/subscription.rb @@ -51,16 +51,7 @@ class CustomWizard::Subscription business: ['*'] }, type: { - none: ['label', 'description', 'image', 'required', 'placeholder', 'file'], - standard: ['*'], - business: ['*'] - }, - prefill: { - standard: ['*'], - business: ['*'] - }, - content: { - none: [], + none: ['text', 'textarea', 'text_only', 'date', 'time', 'date_time', 'number', 'checkbox', 'dropdown', 'upload'], standard: ['*'], business: ['*'] }, @@ -72,8 +63,8 @@ class CustomWizard::Subscription }, action: { type: { - none: [], - standard: ['send_message', 'watch_categories', 'add_to_group'], + none: ['create_topic', 'update_profile', 'open_composer', 'route_to'], + standard: ['create_topic', 'update_profile', 'open_composer', 'route_to', 'send_message', 'watch_categories', 'add_to_group'], business: ['*'] } }, @@ -108,7 +99,7 @@ class CustomWizard::Subscription return false if values.blank? ## Subscription type supports all values of the attribute. - return true if values === "*" + return true if values.first === "*" ## Subscription type supports some values of the attributes. values.include?(value) @@ -168,4 +159,12 @@ class CustomWizard::Subscription def self.type new.type end + + def self.client_installed? + new.client_installed? + end + + def self.includes?(feature, attribute, value) + new.includes?(feature, attribute, value) + end end diff --git a/lib/custom_wizard/validators/template.rb b/lib/custom_wizard/validators/template.rb index 0ffc2608..079f9884 100644 --- a/lib/custom_wizard/validators/template.rb +++ b/lib/custom_wizard/validators/template.rb @@ -54,15 +54,6 @@ class CustomWizard::TemplateValidator } end - def self.subscription - { - wizard: ['save_submissions', 'restart_on_revisit'], - step: ['condition', 'index', 'required_data', 'permitted_params'], - field: ['condition', 'index'], - action: ['type'] - } - end - private def check_required(object, type) @@ -74,8 +65,10 @@ class CustomWizard::TemplateValidator end def validate_subscription(object, type) - self.class.subscription[type].each do |property| - if !@subscription.includes?(type, property, object[property]) + object.keys.each do |property| + value = object[property] + + if !@subscription.includes?(type, property.to_sym, value) errors.add :base, I18n.t("wizard.validation.subscription", type: type.to_s, property: property) end end diff --git a/spec/components/custom_wizard/action_spec.rb b/spec/components/custom_wizard/action_spec.rb index 6149272e..5155a7f4 100644 --- a/spec/components/custom_wizard/action_spec.rb +++ b/spec/components/custom_wizard/action_spec.rb @@ -8,6 +8,7 @@ describe CustomWizard::Action do let(:wizard_template) { get_wizard_fixture("wizard") } let(:open_composer) { get_wizard_fixture("actions/open_composer") } let(:create_category) { get_wizard_fixture("actions/create_category") } + let(:watch_categories) { get_wizard_fixture("actions/watch_categories") } 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") } @@ -158,17 +159,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, {}) @@ -176,11 +166,25 @@ 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 + it 'watches categories' do + watch_categories[:categories][0][:output] = category.id + 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 + + expect(CategoryUser.where( + category_id: category.id, + user_id: user.id + ).first.notification_level).to eq(2) + end + it '#send_message' do wizard_template['actions'] << send_message update_template(wizard_template) @@ -233,9 +237,16 @@ describe CustomWizard::Action do expect(topic.first.allowed_groups.map(&:name)).to include('cool_group', 'cool_group_1') expect(post.exists?).to eq(true) end + end + + context "business subscription actions" do + before do + enable_subscription("business") + end it '#create_category' do wizard_template['actions'] << create_category + wizard_template['actions'] << create_group update_template(wizard_template) wizard = CustomWizard::Builder.new(@template[:id], user).build diff --git a/spec/components/custom_wizard/builder_spec.rb b/spec/components/custom_wizard/builder_spec.rb index 1d7b1213..ebcc355b 100644 --- a/spec/components/custom_wizard/builder_spec.rb +++ b/spec/components/custom_wizard/builder_spec.rb @@ -100,6 +100,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 @@ -304,7 +305,7 @@ describe CustomWizard::Builder 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][0][:condition] = boolean_field_condition_json['condition'] CustomWizard::Template.save(@template.as_json) end @@ -325,7 +326,7 @@ 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][0]['id']) end end end diff --git a/spec/components/custom_wizard/subscription_spec.rb b/spec/components/custom_wizard/subscription_spec.rb new file mode 100644 index 00000000..984eff9f --- /dev/null +++ b/spec/components/custom_wizard/subscription_spec.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +describe CustomWizard::Subscription do + def undefine_client_classes + Object.send(:remove_const, :SubscriptionClient) if Object.constants.include?(:SubscriptionClient) + Object.send(:remove_const, :SubscriptionClientSubscription) if Object.constants.include?(:SubscriptionClientSubscription) + end + + def define_client_classes + load File.expand_path("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/subscription_client.rb", __FILE__) + end + + def stub_client_methods + [:active, :where, :order, :first].each do |method| + SubscriptionClientSubscription.stubs(method) + .returns(SubscriptionClientSubscription) + end + SubscriptionClientSubscription.stubs(:product_id).returns(SecureRandom.hex(8)) + end + + after do + undefine_client_classes + end + + it "detects the subscription client" do + expect(described_class.client_installed?).to eq(false) + end + + context "without a subscription client" do + it "is not subscribed" do + expect(described_class.subscribed?).to eq(false) + end + + it "has none type" do + subscription = described_class.new + expect(subscription.type).to eq(:none) + end + + it "non subscriber features are included" do + expect(described_class.includes?(:wizard, :after_signup, true)).to eq(true) + end + + it "ubscriber features are not included" do + expect(described_class.includes?(:wizard, :permitted, {})).to eq(false) + end + end + + context "with subscription client" do + before do + define_client_classes + stub_client_methods + end + + it "detects the subscription client" do + expect(described_class.client_installed?).to eq(true) + end + + context "without a subscription" do + it "has none type" do + expect(described_class.type).to eq(:none) + end + + it "non subscriber features are included" do + expect(described_class.includes?(:wizard, :after_signup, true)).to eq(true) + end + + it "subscriber features are not included" do + expect(described_class.includes?(:wizard, :permitted, {})).to eq(false) + end + end + + context "with standard subscription" do + before do + SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::STANDARD_PRODUCT_ID) + end + + it "detects standard type" do + expect(described_class.type).to eq(:standard) + end + + it "standard features are included" do + expect(described_class.includes?(:wizard, :type, 'send_message')).to eq(true) + end + + it "business features are not included" do + expect(described_class.includes?(:action, :type, 'create_category')).to eq(false) + end + end + + context "with business subscription" do + before do + SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::BUSINESS_PRODUCT_ID) + end + + it "detects business type" do + expect(described_class.type).to eq(:business) + end + + it "business are included" do + expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) + end + end + end +end diff --git a/spec/components/custom_wizard/template_spec.rb b/spec/components/custom_wizard/template_spec.rb index 14e1659b..63ea25c6 100644 --- a/spec/components/custom_wizard/template_spec.rb +++ b/spec/components/custom_wizard/template_spec.rb @@ -47,6 +47,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 3561e272..b149706f 100644 --- a/spec/components/custom_wizard/template_validator_spec.rb +++ b/spec/components/custom_wizard/template_validator_spec.rb @@ -5,6 +5,8 @@ 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") } + let(:composer_preview) { get_wizard_fixture("field/composer_preview") } let(:valid_liquid_template) { <<-LIQUID.strip @@ -104,7 +106,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) @@ -134,11 +136,11 @@ describe CustomWizard::TemplateValidator do context "with subscription" do before do - enable_subscription("standard") + enable_subscription("business") end it "validates wizard attributes" do - template[:save_submissions] = false + template[:permitted] = permitted_json['permitted'] expect( CustomWizard::TemplateValidator.new(template).perform ).to eq(true) @@ -227,7 +229,9 @@ describe CustomWizard::TemplateValidator do end it "validates preview templates" do - template[:steps][0][:fields][4][:preview_template] = invalid_liquid_template + enable_subscription("standard") + template[:steps][0][:fields] << composer_preview + template[:steps][0][:fields][3][:preview_template] = invalid_liquid_template expect_validation_failure("step_1_field_5.preview_template", liquid_syntax_error) end end diff --git a/spec/components/custom_wizard/update_validator_spec.rb b/spec/components/custom_wizard/update_validator_spec.rb index a01f70d7..7caa1784 100644 --- a/spec/components/custom_wizard/update_validator_spec.rb +++ b/spec/components/custom_wizard/update_validator_spec.rb @@ -3,6 +3,7 @@ describe CustomWizard::UpdateValidator do fab!(:user) { Fabricate(:user) } let(:template) { get_wizard_fixture("wizard") } + let(:url_field) { get_wizard_fixture("field/url") } before do CustomWizard::Template.save(template, skip_jobs: true) @@ -21,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) @@ -34,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 @@ -46,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. " @@ -59,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 @@ -71,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." @@ -84,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 @@ -131,25 +114,33 @@ describe CustomWizard::UpdateValidator do ).to eq(I18n.t('wizard.field.required', label: 'Textarea')) end - it 'validates url fields' do - updater = perform_validation('step_2', step_2_field_6: 'https://discourse.com') - expect( - updater.errors.messages[:step_2_field_6].first - ).to eq(nil) - end + context "subscription fields" do + before do + enable_subscription("standard") + end - it 'does not validate url fields with non-url inputs' do - updater = perform_validation('step_2', step_2_field_6: 'discourse') - expect( - updater.errors.messages[:step_2_field_6].first - ).to eq(I18n.t('wizard.field.not_url', label: 'Url')) - end + it 'validates url fields' do + updater = perform_validation('step_2', step_2_field_6: 'https://discourse.com') + expect( + updater.errors.messages[:step_2_field_6].first + ).to eq(nil) + end - it 'validates empty url fields' do - updater = perform_validation('step_2', step_2_field_6: '') - expect( - updater.errors.messages[:step_2_field_6].first - ).to eq(nil) + it 'does not validate url fields with non-url inputs' do + template[:steps][0][:fields] << url_field + CustomWizard::Template.save(template) + updater = perform_validation('step_1', step_2_field_6: 'discourse') + expect( + updater.errors.messages[:step_2_field_6].first + ).to eq(I18n.t('wizard.field.not_url', label: 'Url')) + end + + it 'validates empty url fields' do + updater = perform_validation('step_2', step_2_field_6: '') + expect( + updater.errors.messages[:step_2_field_6].first + ).to eq(nil) + end end it 'validates date fields' do diff --git a/spec/components/custom_wizard/wizard_spec.rb b/spec/components/custom_wizard/wizard_spec.rb index 00354bf1..5dc1cb95 100644 --- a/spec/components/custom_wizard/wizard_spec.rb +++ b/spec/components/custom_wizard/wizard_spec.rb @@ -113,69 +113,91 @@ describe CustomWizard::Wizard do expect(wizard.completed?).to eq(false) end - it "permits admins" do - expect( - CustomWizard::Wizard.new(@permitted_template, admin_user).permitted? - ).to eq(true) - end + context "with subscription" do + before do + enable_subscription("standard") + end - it "permits permitted users" do - expect( - CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted? - ).to eq(true) - end + it "permits admins" do + expect( + CustomWizard::Wizard.new(@permitted_template, admin_user).permitted? + ).to eq(true) + end - it "permits everyone if everyone is permitted" do - @permitted_template['permitted'][0]['output'] = Group::AUTO_GROUPS[:everyone] - expect( - CustomWizard::Wizard.new(@permitted_template, user).permitted? - ).to eq(true) - end + it "permits permitted users" do + expect( + CustomWizard::Wizard.new(@permitted_template, trusted_user).permitted? + ).to eq(true) + end - it "does not permit unpermitted users" do - expect( - CustomWizard::Wizard.new(@permitted_template, user).permitted? - ).to eq(false) - end + it "permits everyone if everyone is permitted" do + @permitted_template['permitted'][0]['output'] = Group::AUTO_GROUPS[:everyone] + expect( + CustomWizard::Wizard.new(@permitted_template, user).permitted? + ).to eq(true) + end - it "does not let an unpermitted user access a wizard" do - expect( - CustomWizard::Wizard.new(@permitted_template, user).can_access? - ).to eq(false) - end + it "does not permit unpermitted users" do + expect( + CustomWizard::Wizard.new(@permitted_template, user).permitted? + ).to eq(false) + end - it "lets a permitted user access an incomplete wizard" do - expect( - CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? - ).to eq(true) - end + it "does not let an unpermitted user access a wizard" do + expect( + CustomWizard::Wizard.new(@permitted_template, user).can_access? + ).to eq(false) + end - it "lets a permitted user access a complete wizard with multiple submissions" do - append_steps + it "lets a permitted user access an incomplete wizard" do + expect( + CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? + ).to eq(true) + end - progress_step("step_1", acting_user: trusted_user) - progress_step("step_2", acting_user: trusted_user) - progress_step("step_3", acting_user: trusted_user) + it "lets a permitted user access a complete wizard with multiple submissions" do + append_steps - @permitted_template["multiple_submissions"] = true + progress_step("step_1", acting_user: trusted_user) + progress_step("step_2", acting_user: trusted_user) + progress_step("step_3", acting_user: trusted_user) - expect( - CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? - ).to eq(true) - end + @permitted_template["multiple_submissions"] = true - it "does not let an unpermitted user access a complete wizard without multiple submissions" do - append_steps + expect( + CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? + ).to eq(true) + end - progress_step("step_1", acting_user: trusted_user) - progress_step("step_2", acting_user: trusted_user) - progress_step("step_3", acting_user: trusted_user) + it "does not let an unpermitted user access a complete wizard without multiple submissions" do + append_steps - @permitted_template['multiple_submissions'] = false + progress_step("step_1", acting_user: trusted_user) + progress_step("step_2", acting_user: trusted_user) + progress_step("step_3", acting_user: trusted_user) - expect( - CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? - ).to eq(false) + @permitted_template['multiple_submissions'] = false + + expect( + CustomWizard::Wizard.new(@permitted_template, trusted_user).can_access? + ).to eq(false) + end + + it "sets wizard redirects if user is permitted" do + CustomWizard::Template.save(@permitted_template, skip_jobs: true) + CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', trusted_user) + expect( + trusted_user.custom_fields['redirect_to_wizard'] + ).to eq("super_mega_fun_wizard") + end + + it "does not set a wizard redirect if user is not permitted" do + CustomWizard::Template.save(@permitted_template, skip_jobs: true) + CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', user) + expect( + trusted_user.custom_fields['redirect_to_wizard'] + ).to eq(nil) + end end it "lists the site groups" do @@ -203,6 +225,7 @@ describe CustomWizard::Wizard do context "class methods" do before do + enable_subscription("standard") CustomWizard::Template.save(@permitted_template, skip_jobs: true) template_json_2 = template_json.dup @@ -238,20 +261,4 @@ describe CustomWizard::Wizard do expect(CustomWizard::Wizard.prompt_completion(user).length).to eq(1) end end - - it "sets wizard redirects if user is permitted" do - CustomWizard::Template.save(@permitted_template, skip_jobs: true) - CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', trusted_user) - expect( - trusted_user.custom_fields['redirect_to_wizard'] - ).to eq("super_mega_fun_wizard") - end - - it "does not set a wizard redirect if user is not permitted" do - CustomWizard::Template.save(@permitted_template, skip_jobs: true) - CustomWizard::Wizard.set_user_redirect('super_mega_fun_wizard', user) - expect( - trusted_user.custom_fields['redirect_to_wizard'] - ).to eq(nil) - end end diff --git a/spec/fixtures/actions/watch_categories.json b/spec/fixtures/actions/watch_categories.json new file mode 100644 index 00000000..20644f44 --- /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": "", + "output_type": "text", + "output_connector": "set" + } + ], + "mute_remainder": [ + { + "type": "assignment", + "output": "true", + "output_type": "text", + "output_connector": "set" + } + ] +} diff --git a/spec/fixtures/field/advanced_types.json b/spec/fixtures/field/advanced_types.json new file mode 100644 index 00000000..63357cdb --- /dev/null +++ b/spec/fixtures/field/advanced_types.json @@ -0,0 +1,27 @@ +{ + "fields": [ + { + "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", + "label": "User Selector", + "description": "", + "type": "user_selector" + } + ] +} diff --git a/spec/fixtures/field/composer_preview.json b/spec/fixtures/field/composer_preview.json new file mode 100644 index 00000000..f4bec04a --- /dev/null +++ b/spec/fixtures/field/composer_preview.json @@ -0,0 +1,7 @@ +{ + "id": "step_1_field_5", + "label": "I'm a preview", + "description": "", + "type": "composer_preview", + "preview_template": "w{step_1_field_1}" +} diff --git a/spec/fixtures/field/url.json b/spec/fixtures/field/url.json new file mode 100644 index 00000000..e3153fe9 --- /dev/null +++ b/spec/fixtures/field/url.json @@ -0,0 +1,5 @@ +{ + "id": "step_2_field_6", + "label": "Url", + "type": "url" +} diff --git a/spec/fixtures/subscription_client.rb b/spec/fixtures/subscription_client.rb new file mode 100644 index 00000000..a041b507 --- /dev/null +++ b/spec/fixtures/subscription_client.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module SubscriptionClient; end +class SubscriptionClientSubscription; end diff --git a/spec/fixtures/wizard.json b/spec/fixtures/wizard.json index a05c1782..de5e636e 100644 --- a/spec/fixtures/wizard.json +++ b/spec/fixtures/wizard.json @@ -33,23 +33,11 @@ "type": "textarea", "min_length": "" }, - { - "id": "step_1_field_3", - "label": "Composer", - "type": "composer" - }, { "id": "step_1_field_4", "label": "I'm only text", "description": "", "type": "text_only" - }, - { - "id": "step_1_field_5", - "label": "I'm a preview", - "description": "", - "type": "composer_preview", - "preview_template": "w{step_1_field_1}" } ], "description": "Text inputs!" @@ -87,11 +75,6 @@ "label": "Checkbox", "type": "checkbox" }, - { - "id": "step_2_field_6", - "label": "Url", - "type": "url" - }, { "id": "step_2_field_7", "label": "Upload", @@ -141,35 +124,6 @@ ] } ] - }, - { - "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", - "label": "User Selector", - "description": "", - "type": "user_selector" - }, - { - "id": "step_3_field_6", - "label": "Conditional User Selector", - "description": "Shown when checkbox in step_2_field_5 is true", - "type": "user_selector" } ], "description": "Unfortunately not the edible type :sushi: " @@ -264,29 +218,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", diff --git a/spec/plugin_helper.rb b/spec/plugin_helper.rb index f7818296..a0189de1 100644 --- a/spec/plugin_helper.rb +++ b/spec/plugin_helper.rb @@ -7,3 +7,9 @@ def get_wizard_fixture(path) ).read ).with_indifferent_access end + +def enable_subscription(type) + CustomWizard::Subscription.stubs(:client_installed?).returns(true) + CustomWizard::Subscription.stubs("#{type}?".to_sym).returns(true) + CustomWizard::Subscription.any_instance.stubs("#{type}?".to_sym).returns(true) +end diff --git a/spec/requests/custom_wizard/admin/wizard_controller_spec.rb b/spec/requests/custom_wizard/admin/wizard_controller_spec.rb index fd2fa006..9f63cb6b 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 before do CustomWizard::Template.save(template, skip_jobs: true) + enable_subscription("standard") template_2 = template.dup template_2["id"] = 'super_mega_fun_wizard_2' diff --git a/spec/requests/custom_wizard/steps_controller_spec.rb b/spec/requests/custom_wizard/steps_controller_spec.rb index 26ba817a..e05ba917 100644 --- a/spec/requests/custom_wizard/steps_controller_spec.rb +++ b/spec/requests/custom_wizard/steps_controller_spec.rb @@ -34,6 +34,7 @@ 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/requests/custom_wizard/wizard_controller_spec.rb b/spec/requests/custom_wizard/wizard_controller_spec.rb index 3d081b8a..aa1f479b 100644 --- a/spec/requests/custom_wizard/wizard_controller_spec.rb +++ b/spec/requests/custom_wizard/wizard_controller_spec.rb @@ -40,14 +40,15 @@ describe CustomWizard::WizardController do end it 'lets user skip if user cant access wizard' do + enable_subscription("standard") @template["permitted"] = permitted_json["permitted"] CustomWizard::Template.save(@template, skip_jobs: true) - put '/w/super-mega-fun-wizard/skip.json' expect(response.status).to eq(200) end it 'returns a no skip message if user is not allowed to skip' do + enable_subscription("standard") @template['required'] = 'true' CustomWizard::Template.save(@template) put '/w/super-mega-fun-wizard/skip.json' diff --git a/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb index c30279b7..1ac2579e 100644 --- a/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb @@ -19,7 +19,7 @@ describe CustomWizard::FieldSerializer do expect(json_array.size).to eq(@wizard.steps.first.fields.size) 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 @@ -29,6 +29,6 @@ describe CustomWizard::FieldSerializer do scope: Guardian.new(user) ).as_json expect(json_array[0][:format]).to eq("YYYY-MM-DD") - expect(json_array[6][:file_types]).to eq(".jpg,.jpeg,.png") + expect(json_array[5][:file_types]).to eq(".jpg,.jpeg,.png") end end diff --git a/spec/serializers/custom_wizard/wizard_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_serializer_spec.rb index 030f109e..526f5259 100644 --- a/spec/serializers/custom_wizard/wizard_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_serializer_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::WizardSerializer do fab!(:category) { Fabricate(:category) } let(:template) { get_wizard_fixture("wizard") } let(:similar_topics_validation) { get_wizard_fixture("field/validation/similar_topics") } + let(:advanced_fields) { get_wizard_fixture("field/advanced_types") } before do CustomWizard::Template.save(template, skip_jobs: true) @@ -52,43 +53,51 @@ describe CustomWizard::WizardSerializer do 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( - 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 + context "advanced fields" do + before do + enable_subscription("standard") + @template[:steps][0][:fields].push(*advanced_fields['fields']) + CustomWizard::Template.save(@template, skip_jobs: true) + end - 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) + 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 - 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 + @template[:steps][0][:fields][0][:validations] = similar_topics_validation[:validations] + 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 + expect(json[:wizard][:categories].present?).to eq(true) + expect(json[:wizard][:uncategorized_category_id].present?).to eq(true) + 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) + 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 - expect(json[:wizard][:groups].present?).to eq(false) + it 'should not return groups if there is not a group selector field' do + @template[:steps][0][:fields].reject! { |f| f["type"] === "group" } + 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