diff --git a/app/controllers/custom_wizard/admin/admin.rb b/app/controllers/custom_wizard/admin/admin.rb index 867be56c..aa8862b6 100644 --- a/app/controllers/custom_wizard/admin/admin.rb +++ b/app/controllers/custom_wizard/admin/admin.rb @@ -8,7 +8,7 @@ class CustomWizard::AdminController < ::Admin::AdminController subscribed: subcription.subscribed?, subscription_type: subcription.type, subscription_attributes: CustomWizard::Subscription.attributes, - subscription_client_installed: subcription.client_installed? + subscription_client_installed: CustomWizard::Subscription.client_installed? ) end diff --git a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 index 2d13e703..c974fafb 100644 --- a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 +++ b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 @@ -69,7 +69,10 @@ export default { }, _wizardInsertText(text, options) { - if (this.session.wizardEventFieldId === this.fieldId) { + if ( + this.session.wizardEventFieldId === this.fieldId && + this.element + ) { this.insertText(text, options); } }, diff --git a/lib/custom_wizard/api/log_entry.rb b/lib/custom_wizard/api/log_entry.rb index 31af514e..f4f0ce69 100644 --- a/lib/custom_wizard/api/log_entry.rb +++ b/lib/custom_wizard/api/log_entry.rb @@ -65,18 +65,18 @@ class CustomWizard::Api::LogEntry data = ::JSON.parse(record['value']) data[:log_id] = record['key'].split('_').last this_user = User.find_by(id: data['user_id']) - unless this_user.nil? - data[:user_id] = this_user.id || nil - data[:username] = this_user.username || "" - data[:userpath] = "/u/#{this_user.username_lower}/activity" - data[:name] = this_user.name || "" - data[:avatar_template] = "/user_avatar/default/#{this_user.username_lower}/97/#{this_user.uploaded_avatar_id}.png" - else + if this_user.nil? data[:user_id] = nil data[:username] = "" data[:userpath] = "" data[:name] = "" data[:avatar_template] = "" + else + data[:user_id] = this_user.id || nil + data[:username] = this_user.username || "" + data[:userpath] = "/u/#{this_user.username_lower}/activity" + data[:name] = this_user.name || "" + data[:avatar_template] = "/user_avatar/default/#{this_user.username_lower}/97/#{this_user.uploaded_avatar_id}.png" end self.new(api_name, data) end diff --git a/lib/custom_wizard/subscription.rb b/lib/custom_wizard/subscription.rb index dfb75324..6ca592f9 100644 --- a/lib/custom_wizard/subscription.rb +++ b/lib/custom_wizard/subscription.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class CustomWizard::Subscription - STANDARD_PRODUCT_ID = 'prod_MH11woVoZU5AWb' - BUSINESS_PRODUCT_ID = 'prod_MH0wT627okh3Ef' - COMMUNITY_PRODUCT_ID = 'prod_MU7l9EjxhaukZ7' + PRODUCT_HIERARCHY = %w[ + community + standard + business + ] def self.attributes { @@ -99,8 +101,29 @@ class CustomWizard::Subscription } end + attr_accessor :product_id, + :product_slug + def initialize - @subscription = find_subscription + if CustomWizard::Subscription.client_installed? + result = SubscriptionClient.find_subscriptions("discourse-custom-wizard") + + if result&.any? + ids_and_slugs = result.subscriptions.map do |subscription| + { + id: subscription.product_id, + slug: result.products[subscription.product_id] + } + end + + id_and_slug = ids_and_slugs.sort do |a, b| + PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug]) + end.first + + @product_id = id_and_slug[:id] + @product_slug = id_and_slug[:slug] + end + end end def includes?(feature, attribute, value = nil) @@ -140,38 +163,21 @@ class CustomWizard::Subscription end def standard? - @subscription.product_id === STANDARD_PRODUCT_ID + product_slug === "standard" end def business? - @subscription.product_id === BUSINESS_PRODUCT_ID + product_slug === "business" end def community? - @subscription.product_id === COMMUNITY_PRODUCT_ID + product_slug === "community" end - def client_installed? + def self.client_installed? defined?(SubscriptionClient) == 'constant' && SubscriptionClient.class == Module end - def find_subscription - subscription = nil - - if client_installed? - subscription = SubscriptionClientSubscription.active - .where(product_id: [STANDARD_PRODUCT_ID, BUSINESS_PRODUCT_ID, COMMUNITY_PRODUCT_ID]) - .order("product_id = '#{BUSINESS_PRODUCT_ID}' DESC") - .first - end - - unless subscription - subscription = OpenStruct.new(product_id: nil) - end - - subscription - end - def self.subscribed? new.subscribed? end @@ -192,10 +198,6 @@ class CustomWizard::Subscription new.type end - def self.client_installed? - new.client_installed? - end - def self.includes?(feature, attribute, value) new.includes?(feature, attribute, value) end diff --git a/plugin.rb b/plugin.rb index afbe31cf..955063f4 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # name: discourse-custom-wizard # about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more. -# version: 2.3.5 +# version: 2.4.3 # authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever # url: https://github.com/paviliondev/discourse-custom-wizard # contact_emails: development@pavilion.tech diff --git a/spec/components/custom_wizard/subscription_spec.rb b/spec/components/custom_wizard/subscription_spec.rb index 2ac191e1..0bfb1839 100644 --- a/spec/components/custom_wizard/subscription_spec.rb +++ b/spec/components/custom_wizard/subscription_spec.rb @@ -2,6 +2,16 @@ describe CustomWizard::Subscription do let(:guests_permitted) { get_wizard_fixture("wizard/guests_permitted") } + let!(:business_product_id) { SecureRandom.hex(8) } + let!(:standard_product_id) { SecureRandom.hex(8) } + let!(:community_product_id) { SecureRandom.hex(8) } + let!(:product_slugs) { + { + "#{business_product_id}" => "business", + "#{standard_product_id}" => "standard", + "#{community_product_id}" => "community" + } + } def undefine_client_classes Object.send(:remove_const, :SubscriptionClient) if Object.constants.include?(:SubscriptionClient) @@ -12,19 +22,12 @@ describe CustomWizard::Subscription do 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 + undefine_client_classes expect(described_class.client_installed?).to eq(false) end @@ -50,7 +53,6 @@ describe CustomWizard::Subscription do context "with subscription client" do before do define_client_classes - stub_client_methods end it "detects the subscription client" do @@ -58,6 +60,10 @@ describe CustomWizard::Subscription do end context "without a subscription" do + before do + SubscriptionClient.stubs(:find_subscriptions).returns(nil) + end + it "has none type" do expect(described_class.type).to eq(:none) end @@ -71,59 +77,82 @@ describe CustomWizard::Subscription do end end - context "with a subscription" do + context "with subscriptions" do + def get_subscription_result(product_ids) + result = SubscriptionClient::Subscriptions::Result.new + result.supplier = SubscriptionClientSupplier.new(product_slugs) + result.resource = SubscriptionClientResource.new + result.subscriptions = product_ids.map { |product_id| SubscriptionClientSubscription.new(product_id) } + result.products = product_slugs + result + end + let!(:business_subscription_result) { get_subscription_result([business_product_id]) } + let!(:standard_subscription_result) { get_subscription_result([standard_product_id]) } + let!(:community_subscription_result) { get_subscription_result([community_product_id]) } + let!(:multiple_subscription_result) { get_subscription_result([community_product_id, business_product_id]) } + it "handles mapped values" do - SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::STANDARD_PRODUCT_ID) + SubscriptionClient.stubs(:find_subscriptions).returns(standard_subscription_result) expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(true) - SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::COMMUNITY_PRODUCT_ID) + SubscriptionClient.stubs(:find_subscriptions).returns(community_subscription_result) expect(described_class.includes?(:wizard, :permitted, guests_permitted["permitted"])).to eq(false) end - end - context "with standard subscription" do - before do - SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::STANDARD_PRODUCT_ID) + context "with a standard subscription" do + before do + SubscriptionClient.stubs(:find_subscriptions).returns(standard_subscription_result) + 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 - it "detects standard type" do - expect(described_class.type).to eq(:standard) + context "with a business subscription" do + before do + SubscriptionClient.stubs(:find_subscriptions).returns(business_subscription_result) + end + + it "detects business type" do + expect(described_class.type).to eq(:business) + end + + it "business features are included" do + expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) + end end - it "standard features are included" do - expect(described_class.includes?(:wizard, :type, 'send_message')).to eq(true) + context "with a community subscription" do + before do + SubscriptionClient.stubs(:find_subscriptions).returns(community_subscription_result) + end + + it "detects community type" do + expect(described_class.type).to eq(:community) + end + + it "community features are included" do + expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) + end end - it "business features are not included" do - expect(described_class.includes?(:action, :type, 'create_category')).to eq(false) - end - end + context "with multiple subscriptions" do + before do + SubscriptionClient.stubs(:find_subscriptions).returns(multiple_subscription_result) + 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 features are included" do - expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) - end - end - - context "with community subscription" do - before do - SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::COMMUNITY_PRODUCT_ID) - end - - it "detects community type" do - expect(described_class.type).to eq(:community) - end - - it "community features are included" do - expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) + it "detects correct type in hierarchy" do + expect(described_class.type).to eq(:business) + end end end end diff --git a/spec/fixtures/subscription_client.rb b/spec/fixtures/subscription_client.rb index a041b507..146279b1 100644 --- a/spec/fixtures/subscription_client.rb +++ b/spec/fixtures/subscription_client.rb @@ -1,4 +1,40 @@ # frozen_string_literal: true -module SubscriptionClient; end -class SubscriptionClientSubscription; end +module SubscriptionClient + def self.find_subscriptions(resource_name) + end +end + +class SubscriptionClientSupplier + attr_reader :product_slugs + + def initialize(product_slugs) + @product_slugs = product_slugs + end +end + +class SubscriptionClientResource +end + +class SubscriptionClientSubscription + attr_reader :product_id + + def initialize(product_id) + @product_id = product_id + end +end + +module SubscriptionClient + class Subscriptions + class Result + attr_accessor :supplier, + :resource, + :subscriptions, + :products + + def any? + supplier.present? && resource.present? && subscriptions.present? && products.present? + end + end + end +end diff --git a/spec/plugin_helper.rb b/spec/plugin_helper.rb index a0189de1..5334c1fa 100644 --- a/spec/plugin_helper.rb +++ b/spec/plugin_helper.rb @@ -9,7 +9,6 @@ def get_wizard_fixture(path) 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/admin_controller_spec.rb b/spec/requests/custom_wizard/admin/admin_controller_spec.rb new file mode 100644 index 00000000..6a7d721c --- /dev/null +++ b/spec/requests/custom_wizard/admin/admin_controller_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +describe CustomWizard::AdminController do + fab!(:admin_user) { Fabricate(:user, admin: true) } + + it "requires an admin" do + get "/admin/wizards.json" + expect(response.status).to eq(404) + end + + context "with an admin" do + before do + sign_in(admin_user) + end + + context "without a subscription" do + it "returns the right subscription details" do + get "/admin/wizards.json" + expect(response.parsed_body["subscribed"]).to eq(false) + expect(response.parsed_body["subscription_attributes"]).to eq(CustomWizard::Subscription.attributes.as_json) + expect(response.parsed_body["subscription_client_installed"]).to eq(false) + end + end + + context "with a subscription" do + before do + enable_subscription("standard") + load File.expand_path("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/subscription_client.rb", __FILE__) + end + + it "returns the right subscription details" do + get "/admin/wizards.json" + expect(response.parsed_body["subscribed"]).to eq(true) + expect(response.parsed_body["subscription_type"]).to eq("standard") + expect(response.parsed_body["subscription_client_installed"]).to eq(true) + end + end + end +end diff --git a/spec/requests/custom_wizard/admin/submissions_controller_spec.rb b/spec/requests/custom_wizard/admin/submissions_controller_spec.rb deleted file mode 100644 index 3c740c85..00000000 --- a/spec/requests/custom_wizard/admin/submissions_controller_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -describe CustomWizard::AdminSubmissionsController do - fab!(:admin_user) { Fabricate(:user, admin: true) } - fab!(:user1) { Fabricate(:user) } - fab!(:user2) { Fabricate(:user) } - fab!(:user3) { Fabricate(:user) } - - let(:template) { get_wizard_fixture("wizard") } - let(:template_2) { - temp = template.dup - temp["id"] = "super_mega_fun_wizard_2" - temp - } - - before do - CustomWizard::Template.save(template, skip_jobs: true) - CustomWizard::Template.save(template_2, skip_jobs: true) - - wizard1 = CustomWizard::Wizard.create(template["id"], user1) - wizard2 = CustomWizard::Wizard.create(template["id"], user2) - wizard3 = CustomWizard::Wizard.create(template_2["id"], user3) - - CustomWizard::Submission.new(wizard1, step_1_field_1: "I am a user1's submission").save - CustomWizard::Submission.new(wizard2, step_1_field_1: "I am a user2's submission").save - CustomWizard::Submission.new(wizard3, step_1_field_1: "I am a user3's submission").save - - sign_in(admin_user) - end - - it "returns a list of wizards" do - get "/admin/wizards/submissions.json" - expect(response.parsed_body.length).to eq(2) - expect(response.parsed_body.first['id']).to eq(template['id']) - end - - it "returns users' submissions for a wizard" do - get "/admin/wizards/submissions/#{template['id']}.json" - expect(response.parsed_body['submissions'].length).to eq(2) - end - - it "downloads submissions" do - get "/admin/wizards/submissions/#{template_2['id']}/download" - expect(response.parsed_body.length).to eq(1) - end -end