From 23b1988b0a86d3ffd61f5490e13f2e942da5d07e Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Wed, 19 Aug 2026 08:41:06 +0200 Subject: [PATCH 1/5] fix: Locale file names We need the locale as suffix for them to have any effect --- config/locales/{alchemy_solidus_en.yml => alchemy_solidus.en.yml} | 0 config/locales/{alchemy_solidus_it.yml => alchemy_solidus.it.yml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename config/locales/{alchemy_solidus_en.yml => alchemy_solidus.en.yml} (100%) rename config/locales/{alchemy_solidus_it.yml => alchemy_solidus.it.yml} (100%) diff --git a/config/locales/alchemy_solidus_en.yml b/config/locales/alchemy_solidus.en.yml similarity index 100% rename from config/locales/alchemy_solidus_en.yml rename to config/locales/alchemy_solidus.en.yml diff --git a/config/locales/alchemy_solidus_it.yml b/config/locales/alchemy_solidus.it.yml similarity index 100% rename from config/locales/alchemy_solidus_it.yml rename to config/locales/alchemy_solidus.it.yml From 3b67c51063d9fab8f0d0874077892a3e184b154b Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Mon, 7 Sep 2026 15:58:19 +0200 Subject: [PATCH 2/5] chore: Remove unused locale file Essences have been removed a long while ago --- config/locales/en.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 config/locales/en.yml diff --git a/config/locales/en.yml b/config/locales/en.yml deleted file mode 100644 index 0cf59a60..00000000 --- a/config/locales/en.yml +++ /dev/null @@ -1,5 +0,0 @@ -en: - alchemy: - essences: - essence_spree_taxon_editor: - none: None From 8c15865abd976a5316bc15dfde04dd1c1ca0ef54 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Wed, 19 Aug 2026 08:30:39 +0200 Subject: [PATCH 3/5] feat: Use Alchemy::UserMethods module Alchemy 8.4 now ships a UserMethods module that handles necessary accesors like a database backed alchemy_roles column and who-dunnit functionality. This aligns the solidus user model with the alchemy-devise user model which has more roles than just "admin". --- Gemfile | 2 +- .../_form/alchemy_roles_field.html.erb.deface | 10 +++ .../spree_admin_users_controller_patch.rb | 19 +++++ .../alchemy/solidus/alchemy_user_patch.rb | 2 +- .../alchemy/solidus/spree_user_patch.rb | 9 +-- config/locales/alchemy_solidus.de.yml | 13 ++++ config/locales/alchemy_solidus.en.yml | 13 ++++ config/locales/alchemy_solidus.it.yml | 13 ++++ .../files/db/migrate/set_alchemy_roles.tt | 18 +++++ .../solidus/install/install_generator.rb | 23 ++++++ spec/dummy/package.json | 4 +- .../alchemy/spree_admin_users_spec.rb | 25 +++++++ .../alchemy/solidus/install_generator_spec.rb | 72 +++++++++++++++++++ spec/models/spree/user_extension_spec.rb | 23 +----- 14 files changed, 213 insertions(+), 33 deletions(-) create mode 100644 app/overrides/spree/admin/users/_form/alchemy_roles_field.html.erb.deface create mode 100644 app/patches/controllers/alchemy/solidus/spree_admin_users_controller_patch.rb create mode 100644 lib/generators/alchemy/solidus/install/files/db/migrate/set_alchemy_roles.tt create mode 100644 spec/features/alchemy/spree_admin_users_spec.rb create mode 100644 spec/generators/alchemy/solidus/install_generator_spec.rb diff --git a/Gemfile b/Gemfile index 7da0399c..d2eecffa 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem "solidus_core", github: "solidusio/solidus", branch: solidus_branch gem "solidus_backend", github: "solidusio/solidus", branch: solidus_branch gem "solidus_frontend", github: "solidusio/solidus_frontend", branch: "main" -alchemy_branch = ENV.fetch("ALCHEMY_BRANCH", "8.3-stable") +alchemy_branch = ENV.fetch("ALCHEMY_BRANCH", "8.4-stable") gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: alchemy_branch gem "alchemy-devise", github: "AlchemyCMS/alchemy-devise", branch: alchemy_branch diff --git a/app/overrides/spree/admin/users/_form/alchemy_roles_field.html.erb.deface b/app/overrides/spree/admin/users/_form/alchemy_roles_field.html.erb.deface new file mode 100644 index 00000000..114df01c --- /dev/null +++ b/app/overrides/spree/admin/users/_form/alchemy_roles_field.html.erb.deface @@ -0,0 +1,10 @@ + + +<%= f.field_container :alchemy_roles do %> + <%= label_tag nil, t(".alchemy_roles") %> + <%= admin_hint t(".alchemy_roles"), t(:alchemy_roles_html, scope: [:spree, :hints, "spree/user"]) %> + <%= f.collection_select :alchemy_roles, Alchemy.config.user_roles, :to_s, :capitalize, + {include_blank: false}, + multiple: true, disabled: cannot?(:update_role, @user), + class: "select2 fullwidth" %> +<% end %> diff --git a/app/patches/controllers/alchemy/solidus/spree_admin_users_controller_patch.rb b/app/patches/controllers/alchemy/solidus/spree_admin_users_controller_patch.rb new file mode 100644 index 00000000..d2409169 --- /dev/null +++ b/app/patches/controllers/alchemy/solidus/spree_admin_users_controller_patch.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Alchemy + module Solidus + module SpreeAdminUsersControllerPatch + private + + def permitted_user_attributes + attributes = super + attributes << {alchemy_roles: []} if can?(:update_role, @user) + attributes + end + + if defined?(::Spree::Admin::UsersController) + ::Spree::Admin::UsersController.prepend self + end + end + end +end diff --git a/app/patches/models/alchemy/solidus/alchemy_user_patch.rb b/app/patches/models/alchemy/solidus/alchemy_user_patch.rb index d3e21fc4..ab919ec1 100644 --- a/app/patches/models/alchemy/solidus/alchemy_user_patch.rb +++ b/app/patches/models/alchemy/solidus/alchemy_user_patch.rb @@ -6,7 +6,7 @@ def self.prepended(klass) end def spree_roles - if admin? + if alchemy_admin? ::Spree::Role.where(name: "admin") else ::Spree::Role.none diff --git a/app/patches/models/alchemy/solidus/spree_user_patch.rb b/app/patches/models/alchemy/solidus/spree_user_patch.rb index 0f2293dc..1cccf31c 100644 --- a/app/patches/models/alchemy/solidus/spree_user_patch.rb +++ b/app/patches/models/alchemy/solidus/spree_user_patch.rb @@ -11,16 +11,9 @@ def alchemy_display_name email end - def alchemy_roles - if has_spree_role?(:admin) - %w[admin] - else - [] - end - end - if defined?(::Spree::User) ::Spree::User.prepend self + ::Spree::User.include Alchemy::UserMethods end end end diff --git a/config/locales/alchemy_solidus.de.yml b/config/locales/alchemy_solidus.de.yml index 7709c3c2..03ce6edc 100644 --- a/config/locales/alchemy_solidus.de.yml +++ b/config/locales/alchemy_solidus.de.yml @@ -18,3 +18,16 @@ de: users: Benutzer pictures: Bilder attachments: Dateien + users: + form: + alchemy_roles: Alchemy Rollen + hints: + spree/user: + alchemy_roles_html: | +

Diese Rollen steuern den Zugriff zum Alchemy CMS.

+
    +
  • Mitglied beschreibt regulär angemeldete Kunden und ermöglicht den Zugriff auf regulär gesicherte Seiten. Sie ermöglicht nicht auf den Admin Bereich zuzugreifen.
  • +
  • Autor ermöglicht Seiteninhalte zu bearbeiten, aber keine Seiten zu erstellen.
  • +
  • Editor ermöglicht vollen Zugriff auf Seiten und Sprachen.
  • +
  • Admin ermöglicht vollen Zugriff auf alles.
  • +
diff --git a/config/locales/alchemy_solidus.en.yml b/config/locales/alchemy_solidus.en.yml index 6b59dc72..b7f7f3c6 100644 --- a/config/locales/alchemy_solidus.en.yml +++ b/config/locales/alchemy_solidus.en.yml @@ -18,3 +18,16 @@ en: users: Users pictures: Pictures attachments: Attachments + users: + form: + alchemy_roles: Alchemy Roles + hints: + spree/user: + alchemy_roles_html: | +

These roles allow access to Alchemy CMS.

+
    +
  • Member describes regular logged in customers and allows to visit regularly restricted pages. It does not grant access to the CMS backend.
  • +
  • Author grants access to edit content but not to create pages.
  • +
  • Editor grants access to fully manage pages and languages.
  • +
  • Admin grants access to manage everything.
  • +
diff --git a/config/locales/alchemy_solidus.it.yml b/config/locales/alchemy_solidus.it.yml index da3e5a2f..3e1c01e1 100644 --- a/config/locales/alchemy_solidus.it.yml +++ b/config/locales/alchemy_solidus.it.yml @@ -9,3 +9,16 @@ it: tags: "Tags" pictures: "Immagini" attachments: "File" + users: + form: + alchemy_roles: Alchemy Ruoli + hints: + spree/user: + alchemy_roles_html: | +

Questi ruoli consentono l'accesso ad Alchemy CMS.

+
    +
  • Membro indica i normali clienti autenticati e consente di visitare le pagine ad accesso limitato. Non concede l'accesso al backend del CMS.
  • +
  • Autore concede l'accesso alla modifica dei contenuti, ma non alla creazione di pagine.
  • +
  • Editore concede l'accesso alla gestione completa di pagine e lingue.
  • +
  • Amministratore concede l'accesso alla gestione di tutto.
  • +
diff --git a/lib/generators/alchemy/solidus/install/files/db/migrate/set_alchemy_roles.tt b/lib/generators/alchemy/solidus/install/files/db/migrate/set_alchemy_roles.tt new file mode 100644 index 00000000..7520e63e --- /dev/null +++ b/lib/generators/alchemy/solidus/install/files/db/migrate/set_alchemy_roles.tt @@ -0,0 +1,18 @@ +class SetAlchemyRolesOn<%= @table_name.camelcase %>Table < ActiveRecord::Migration[7.2] + def up + Spree::User.find_each do |user| + alchemy_roles = if user.has_spree_role?(:admin) + "admin" + elsif user.has_spree_role?(:user) + "member" + end + user.update_column(:alchemy_roles, alchemy_roles) + end + end + + def down + Spree::User.find_each do |user| + user.update_column(:alchemy_roles, nil) + end + end +end diff --git a/lib/generators/alchemy/solidus/install/install_generator.rb b/lib/generators/alchemy/solidus/install/install_generator.rb index a3734e4b..73dc57a3 100644 --- a/lib/generators/alchemy/solidus/install/install_generator.rb +++ b/lib/generators/alchemy/solidus/install/install_generator.rb @@ -1,5 +1,7 @@ require "rails/generators" +require "rails/generators/active_record/migration" require "generators/alchemy/install/install_generator" +require "generators/alchemy/user_columns_migration/user_columns_migration_generator" require "generators/spree/custom_user/custom_user_generator" require "solidus_support" @@ -11,6 +13,8 @@ module Alchemy module Solidus class InstallGenerator < Rails::Generators::Base + include ActiveRecord::Generators::Migration + SPREE_MOUNT_REGEXP = /mount\sSpree::Core::Engine.*$/ desc "Installs Alchemy Solidus into your App." @@ -24,6 +28,11 @@ class InstallGenerator < Rails::Generators::Base type: :boolean, desc: "Set true if you don't want to run the Alchemy Devise installer. NOTE: Automatically skipped if Alchemy::Devise is not available." + class_option :skip_alchemy_user_columns_generator, + default: false, + type: :boolean, + desc: + "Set true if you don't want to run the Alchemy user columns generator. NOTE: Automatically skipped if Spree::User is not available." class_option :skip_spree_custom_user_generator, default: false, type: :boolean, @@ -64,6 +73,20 @@ def run_alchemy_devise_installer end end + def run_alchemy_user_columns_generator + if defined?(::Spree::User) && + !options[:skip_alchemy_user_columns_generator] + @table_name = ::Spree::User.table_name + arguments = [ + "--table-name", + @table_name, options[:auto_accept] && "--force" + ].compact + Alchemy::Generators::UserColumnsMigrationGenerator.start(arguments) + migration_template "db/migrate/set_alchemy_roles.tt", "db/migrate/set_alchemy_roles_on_#{@table_name}_table.rb" + rake("db:migrate", abort_on_failure: true) + end + end + def run_spree_custom_user_generator if alchemy_devise_present? && !options[:skip_spree_custom_user_generator] diff --git a/spec/dummy/package.json b/spec/dummy/package.json index e93a480b..1887cba0 100644 --- a/spec/dummy/package.json +++ b/spec/dummy/package.json @@ -3,9 +3,9 @@ "private": "true", "dependencies": { "@alchemy_cms/admin": "~7.0.0-a", - "esbuild": "^0.18.11" + "esbuild": "^0.28.2" }, "scripts": { - "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets" + "build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets" } } diff --git a/spec/features/alchemy/spree_admin_users_spec.rb b/spec/features/alchemy/spree_admin_users_spec.rb new file mode 100644 index 00000000..7399dd5f --- /dev/null +++ b/spec/features/alchemy/spree_admin_users_spec.rb @@ -0,0 +1,25 @@ +require "rails_helper" +require "spree/testing_support/authorization_helpers" +require "spree/testing_support/capybara_ext" + +RSpec.describe "Spree Admin Users", type: :feature do + stub_authorization! + + describe "editing a user" do + let(:user) { create(:alchemy_user) } + + it "shows the alchemy roles field", :js do + visit spree.edit_admin_user_path(user) + + select2_search "Editor", from: "Alchemy Roles" + # For some weird reason the factory does not create a valid user + # or devise wants us to re-enter the password when updating the user. + # It does not matter, just fill in the password fields. + fill_in "Password", with: user.password + fill_in "Password confirmation", with: user.password + click_button "Update" + expect(page).to have_content("Account updated") + expect(user.reload.alchemy_roles).to include("editor") + end + end +end diff --git a/spec/generators/alchemy/solidus/install_generator_spec.rb b/spec/generators/alchemy/solidus/install_generator_spec.rb new file mode 100644 index 00000000..1ba4b151 --- /dev/null +++ b/spec/generators/alchemy/solidus/install_generator_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "rails_helper" +require "tmpdir" +require "generators/alchemy/solidus/install/install_generator" + +RSpec.describe Alchemy::Solidus::InstallGenerator do + describe "#run_alchemy_user_columns_generator" do + around do |example| + Dir.mktmpdir("alchemy-solidus-install-generator") do |dir| + @destination_root = dir + # The Alchemy user columns generator is invoked via `.start`, which + # resolves its destination from the working directory, not from ours. + Dir.chdir(dir) { example.run } + end + end + + attr_reader :destination_root + + let(:generator) do + described_class.new([], {auto_accept: true}, destination_root: destination_root) + end + + let(:add_columns_migration) do + Dir.glob(File.join(destination_root, "db", "migrate", "*_add_alchemy_fields_to_spree_users_table.rb")).first + end + + let(:set_roles_migration) do + Dir.glob(File.join(destination_root, "db", "migrate", "*_set_alchemy_roles_on_spree_users_table.rb")).first + end + + before do + stub_const("Spree::User", Class.new(ActiveRecord::Base) do + self.table_name = "spree_users" + end) + allow(generator).to receive(:rake) + silence_stream { generator.run_alchemy_user_columns_generator } + end + + def silence_stream + original, $stdout = $stdout, StringIO.new + yield + ensure + $stdout = original + end + + it "adds the Alchemy columns to the Spree user table" do + expect(add_columns_migration).to be_present + end + + it "backfills the Alchemy roles on the Spree user table" do + expect(set_roles_migration).to be_present + end + + it "names the migration classes after their files" do + expect(File.read(add_columns_migration)).to include( + "class AddAlchemyFieldsToSpreeUsersTable < ActiveRecord::Migration" + ) + expect(File.read(set_roles_migration)).to include( + "class SetAlchemyRolesOnSpreeUsersTable < ActiveRecord::Migration" + ) + end + + it "assigns the Alchemy roles as strings" do + content = File.read(set_roles_migration) + + # `update_column` casts through the text column and raises on an Array. + expect(content).to include('"admin"', '"member"') + expect(content).to include("user.update_column(:alchemy_roles, alchemy_roles)") + end + end +end diff --git a/spec/models/spree/user_extension_spec.rb b/spec/models/spree/user_extension_spec.rb index 5ce990d7..af8d7f5a 100644 --- a/spec/models/spree/user_extension_spec.rb +++ b/spec/models/spree/user_extension_spec.rb @@ -9,34 +9,15 @@ def self.name "Spree::User" end - def has_spree_role?(_role) - false - end - include Alchemy::Solidus::SpreeUserPatch end end let(:user) { spree_user.new(email: "spree@example.com") } - describe "#alchemy_roles" do - context "when user is an admin" do - it "returns an array with the admin role" do - allow(user).to receive(:has_spree_role?).with(:admin).and_return(true) - expect(user.alchemy_roles).to eq %w[admin] - end - end - - context "when user is not an admin" do - it { expect(user.alchemy_roles).to be_empty } - end - end - describe "#alchemy_display_name" do - context "when user is not an admin" do - it "returns user's email" do - expect(user.alchemy_display_name).to eq "spree@example.com" - end + it "returns user's email" do + expect(user.alchemy_display_name).to eq "spree@example.com" end end end From 4fd4078a2d6b66c4bfd53112e2e5253181eaba79 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Wed, 9 Sep 2026 16:59:09 +0200 Subject: [PATCH 4/5] feat: Update custom selects for Alchemy 8.4 Alchemy 8.4 switched from Select2 to Tom Select for Remote Selects. --- .github/workflows/test.yml | 4 +- .../components/product_select.js | 28 ++++++----- .../components/taxon_select.js | 28 ++++++----- .../components/variant_select.js | 47 ++++++++----------- spec/features/alchemy/link_overlay_spec.rb | 7 ++- spec/rails_helper.rb | 9 +++- 6 files changed, 66 insertions(+), 57 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec2292e4..9c4d3368 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ concurrency: jobs: Rspec: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -21,7 +21,7 @@ jobs: - "3.4" - "4.0" alchemy: - - "8.3-stable" + - "8.4-stable" - "main" solidus: - "v4.5" diff --git a/app/javascript/alchemy_solidus/components/product_select.js b/app/javascript/alchemy_solidus/components/product_select.js index e91855b0..bb808048 100644 --- a/app/javascript/alchemy_solidus/components/product_select.js +++ b/app/javascript/alchemy_solidus/components/product_select.js @@ -15,7 +15,7 @@ export default class ProductSelect extends RemoteSelect { } /** - * Parses server response into select2 results object + * Parses server response into a results object * @param {object} response * @returns {object} * @private @@ -48,24 +48,28 @@ export default class ProductSelect extends RemoteSelect { } /** - * result which is visible if a product was selected + * slots of a dropdown option * @param {object} product - * @returns {string} - * @private + * @param {string} term + * @returns {object} + * @protected */ - _renderResult(product) { - return product.name + _entry(product, term) { + return { + primary: this._hightlightTerm(product.name, term) + } } /** - * html template for each list entry + * slots of the selected product shown in the control * @param {object} product - * @param {string} term - * @returns {string} - * @private + * @returns {object} + * @protected */ - _renderListEntry(product, term) { - return this._hightlightTerm(product.name, term) + _selectedEntry(product) { + return { + primary: product.name + } } } diff --git a/app/javascript/alchemy_solidus/components/taxon_select.js b/app/javascript/alchemy_solidus/components/taxon_select.js index cc5f19cc..01380f3d 100644 --- a/app/javascript/alchemy_solidus/components/taxon_select.js +++ b/app/javascript/alchemy_solidus/components/taxon_select.js @@ -11,7 +11,7 @@ export default class TaxonSelect extends RemoteSelect { } /** - * Parses server response into select2 results object + * Parses server response into a results object * @param {object} response * @returns {object} * @private @@ -24,24 +24,28 @@ export default class TaxonSelect extends RemoteSelect { } /** - * result which is visible if a taxon was selected + * slots of a dropdown option * @param {object} taxon - * @returns {string} - * @private + * @param {string} term + * @returns {object} + * @protected */ - _renderResult(taxon) { - return taxon.text || taxon.pretty_name + _entry(taxon, term) { + return { + primary: this._hightlightTerm(taxon.pretty_name, term) + } } /** - * html template for each list entry + * slots of the selected taxon shown in the control * @param {object} taxon - * @param {string} term - * @returns {string} - * @private + * @returns {object} + * @protected */ - _renderListEntry(taxon, term) { - return this._hightlightTerm(taxon.pretty_name, term) + _selectedEntry(taxon) { + return { + primary: taxon.text || taxon.pretty_name + } } } diff --git a/app/javascript/alchemy_solidus/components/variant_select.js b/app/javascript/alchemy_solidus/components/variant_select.js index 43a4be1a..330f6888 100644 --- a/app/javascript/alchemy_solidus/components/variant_select.js +++ b/app/javascript/alchemy_solidus/components/variant_select.js @@ -11,7 +11,7 @@ export default class VariantSelect extends RemoteSelect { } /** - * Search query send to server from select2 + * Search query send to server * @param {string} term * @param {number} page * @returns {object} @@ -28,7 +28,7 @@ export default class VariantSelect extends RemoteSelect { } /** - * Parses server response into select2 results object + * Parses server response into a results object * @param {object} response * @returns {object} * @private @@ -41,38 +41,31 @@ export default class VariantSelect extends RemoteSelect { } /** - * result which is visible if a variant was selected + * slots of a dropdown option * @param {object} variant - * @returns {string} - * @private + * @param {string} term + * @returns {object} + * @protected */ - _renderResult(variant) { - return variant.options_text - ? `${variant.name} - ${variant.options_text}` - : variant.name + _entry(variant, term) { + return { + primary: this._hightlightTerm(variant.name, term), + secondary: variant.options_text, + secondaryAside: variant.sku + } } /** - * html template for each list entry + * slots of the selected variant shown in the control * @param {object} variant - * @param {string} term - * @returns {string} - * @private + * @returns {object} + * @protected */ - _renderListEntry(variant, term) { - const name = this._hightlightTerm(variant.name, term) - const sku = this._hightlightTerm(variant.sku, term) - return ` -
-
- ${name} -
-
- ${variant.options_text} - ${sku} -
-
- ` + _selectedEntry(variant) { + return { + primary: variant.name, + secondary: variant.options_text + } } } diff --git a/spec/features/alchemy/link_overlay_spec.rb b/spec/features/alchemy/link_overlay_spec.rb index 3faabd17..64c0617f 100644 --- a/spec/features/alchemy/link_overlay_spec.rb +++ b/spec/features/alchemy/link_overlay_spec.rb @@ -2,8 +2,11 @@ require "rails_helper" require "alchemy/devise/test_support/factories" +require "alchemy/test_support/capybara_helpers" RSpec.describe "Link overlay" do + include Alchemy::TestSupport::CapybaraHelpers + let(:a_page) { create(:alchemy_page) } let(:element) do @@ -56,8 +59,8 @@ end within "[name=overlay_tab_product_link]" do - expect(page).to have_selector("#s2id_product_link") - select2_search(product.name, from: "Product") + expect(page).to have_selector("#product_link-ts-control") + tom_select_search(product.name, from: "Product") click_button "apply" end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index b5840c08..606af754 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -45,7 +45,6 @@ Spree::TestingSupport::FactoryBot.add_paths_and_load! require "alchemy/test_support" -require "alchemy/test_support/capybara_helpers" require "alchemy/test_support/integration_helpers" FactoryBot.definition_file_paths.append(Alchemy::TestSupport.factories_path) @@ -77,7 +76,6 @@ RSpec.configure do |config| config.include Alchemy::TestSupport::IntegrationHelpers, type: :feature - config.include Alchemy::TestSupport::CapybaraHelpers, type: :feature config.include ActiveSupport::Testing::TimeHelpers, type: :model config.include ViewComponent::TestHelpers, type: :component @@ -107,4 +105,11 @@ # config.filter_gems_from_backtrace("gem name") config.include FactoryBot::Syntax::Methods + + # TODO Remove when Devise fixes https://github.com/heartcombo/devise/issues/5705 + if Rails.application.respond_to?(:reload_routes_unless_loaded) + config.before(:each, type: :feature) do + Rails.application.reload_routes_unless_loaded + end + end end From dffd1172dde0e13c227249da942126bcc84a031b Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Thu, 10 Sep 2026 17:27:39 +0200 Subject: [PATCH 5/5] chore: Remove package.json from dummy app Not necessary anymore since Alchemy 8.0 --- spec/dummy/package.json | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 spec/dummy/package.json diff --git a/spec/dummy/package.json b/spec/dummy/package.json deleted file mode 100644 index 1887cba0..00000000 --- a/spec/dummy/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "app", - "private": "true", - "dependencies": { - "@alchemy_cms/admin": "~7.0.0-a", - "esbuild": "^0.28.2" - }, - "scripts": { - "build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets" - } -}