Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,15 @@ jobs:
fail-fast: false
matrix:
ruby-version:
- "3.1"
- "3.2"
- "3.3"
- "3.4"
alchemy:
- "7.2-stable"
- "7.3-stable"
- "7.4-stable"
- "8.0-stable"
solidus:
- "v4.1"
- "v4.2"
- "v4.3"
- "v4.4"
- "v4.5"
- "v4.6"
env:
ALCHEMY_BRANCH: ${{ matrix.alchemy }}
SOLIDUS_BRANCH: ${{ matrix.solidus }}
Expand Down
11 changes: 6 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
source "https://rubygems.org"

solidus_branch = ENV.fetch("SOLIDUS_BRANCH", "v4.4")
solidus_branch = ENV.fetch("SOLIDUS_BRANCH", "v4.6")
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", "7.4-stable")
alchemy_branch = ENV.fetch("ALCHEMY_BRANCH", "8.0-stable")
gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: alchemy_branch

gem "alchemy-devise", github: "AlchemyCMS/alchemy-devise", branch: "7.4-stable"
gem "alchemy-devise", github: "AlchemyCMS/alchemy-devise", branch: alchemy_branch

# Specify your gem's dependencies in alchemy-solidus.gemspec
gemspec

gem "sqlite3", "~> 1.4"
gem "sqlite3", "~> 2.7"
gem "pry-rails"
gem "sprockets", "~> 4.0"
gem "jsbundling-rails", "~> 1.1"
Expand All @@ -36,3 +35,5 @@ group :lint do
gem "rubocop", require: false
gem "standard", "~> 1.25", require: false
end

gem "ruby-lsp-rspec", "~> 0.1.28"
5 changes: 3 additions & 2 deletions alchemy-solidus.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"]
gem.version = Alchemy::Solidus::VERSION

gem.add_dependency("alchemy_cms", [">= 7.2.0", "< 8"])
gem.add_dependency("alchemy_cms", [">= 7.2.0", "< 9"])
gem.add_dependency("solidus_api", [">= 4.0.0", "< 5"])
gem.add_dependency("solidus_core", [">= 4.0.0", "< 5"])
gem.add_dependency("solidus_backend", [">= 4.0.0", "< 5"])
gem.add_dependency("solidus_support", [">= 0.14.0", "< 1"])
gem.add_dependency("deface", ["~> 1.0"])

gem.add_development_dependency("rspec-rails", ["~> 6.0"])
gem.add_development_dependency("rspec-rails", ["~> 8.0"])
gem.add_development_dependency("shoulda-matchers", ["~> 4.0"])
gem.add_development_dependency("capybara", ["~> 3.0"])
gem.add_development_dependency("capybara-screenshot", ["~> 1.0"])
Expand Down
7 changes: 2 additions & 5 deletions app/components/alchemy/admin/link_dialog/product_tab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ def message
private

def product
slug = url&.match(/products\/(?<slug>[\w-]+)/)&.captures
return unless slug

@_product ||= Spree::Product.find_by(slug: slug)
@_product ||= Alchemy::Solidus.config.product_finder.call(url)
end

def product_select
Expand All @@ -48,7 +45,7 @@ def product_select
current_alchemy_user.spree_api_key,
product: product,
url: spree.api_products_path,
value_attribute: :slug
value_attribute: Alchemy::Solidus.config.product_url_attribute
).with_content(input)
content_tag("div", label + select, class: "input select")
end
Expand Down
12 changes: 3 additions & 9 deletions app/components/alchemy/admin/product_select.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
module Alchemy
module Admin
class ProductSelect < ViewComponent::Base
VALUE_ATTRIBUTES = %i[id slug].freeze

delegate :spree, to: :helpers

attr_reader :api_key, :product, :url, :query_params, :placeholder
attr_reader :api_key, :product, :url, :query_params, :placeholder, :value_attribute

def initialize(api_key, product: nil, url: nil, query_params: nil, placeholder: nil, value_attribute: nil)
@api_key = api_key
@product = product
@url = url
@query_params = query_params
@placeholder = placeholder
@value_attribute = value_attribute
@value_attribute = value_attribute || :id
end

def call
Expand All @@ -22,10 +20,6 @@ def call

private

def value_attribute
@value_attribute.in?(VALUE_ATTRIBUTES) ? @value_attribute : :id
end

def attributes
attrs = {
placeholder: placeholder || Alchemy.t(:search_product, scope: "solidus"),
Expand All @@ -45,7 +39,7 @@ def attributes

def serialized_selection
{
id: product.send(value_attribute),
id: product.public_send(value_attribute),
name: product.name
}.to_json
end
Expand Down
6 changes: 1 addition & 5 deletions app/javascript/alchemy_solidus/components/product_select.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,11 @@ export default class ProductSelect extends RemoteSelect {
* The value used for the select send to the server
* after submitting the form this select is placed in.
*
* Note: Returning an url if the `value-attribute` is "slug".
*
* @param {object} product
* @returns {string}
*/
_parsedValue(product) {
return this.valueAttribute === "slug"
? `${Spree.mountedAt()}products/${product.slug}`
: product.id
return product[this.valueAttribute]
}

/**
Expand Down
18 changes: 18 additions & 0 deletions app/models/alchemy/solidus/product_finder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Alchemy
module Solidus
# Finds a Spree::Product by its slug.
#
module ProductFinder
extend self

# @param url [String] The URL to find the product by.
# @return [Spree::Product, nil] The found product or nil if not found.
def call(url)
slug = url&.match(/products\/(?<slug>[\w-]+)/)&.captures
return unless slug

Spree::Product.find_by(slug:)
end
end
end
end
4 changes: 4 additions & 0 deletions app/patches/models/alchemy/solidus/spree_product_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def self.prepended(base)
base.has_many :alchemy_ingredients, class_name: "Alchemy::Ingredients::SpreeProduct", as: :related_object, dependent: :nullify
end

def url_path
Spree::Core::Engine.routes.url_helpers.try(:product_path, self)
end

private

# Overwritten Solidus' default behavior
Expand Down
2 changes: 1 addition & 1 deletion config/initializers/alchemy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@

Rails.application.config.after_initialize do
Alchemy::Modules.register_module(alchemy_module)
Alchemy.link_dialog_tabs.add(Alchemy::Admin::LinkDialog::ProductTab)
Alchemy.config.link_dialog_tabs.add("Alchemy::Admin::LinkDialog::ProductTab")
end
1 change: 1 addition & 0 deletions config/initializers/spree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
end

Rails.application.config.after_initialize do
Spree::Api::Config.product_attributes << :url_path
Spree::Backend::Config.configure do |config|
alchemy_menu_item = if Spree.solidus_gem_version >= Gem::Version.new("4.2.0")
config.class::MenuItem.new(
Expand Down
12 changes: 12 additions & 0 deletions lib/alchemy-solidus.rb
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
require "alchemy/solidus/configuration"

module Alchemy
module Solidus
extend self

def config
@_config ||= Alchemy::Solidus::Configuration.new
end
end
end

require "alchemy/solidus/engine"
27 changes: 27 additions & 0 deletions lib/alchemy/solidus/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require "alchemy/configuration"

module Alchemy
module Solidus
class Configuration < Alchemy::Configuration
# == This is the Alchemy Solidus configuration class

# === Product URL Attribute
#
# The Spree::Product attribute we use for url.
#
# NOTE: Used in the Product Select.
#
option :product_url_attribute, :string, default: "url_path"

# === Product URL Finder
#
# The class responsible to load the product by url.
#
# NOTE: Used in the Page Link Dialogs Product Tab.
#
option :product_finder, :class, default: "Alchemy::Solidus::ProductFinder"
end
end
end
3 changes: 2 additions & 1 deletion lib/alchemy/solidus/engine.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "alchemy_cms"
require "alchemy/version"
require "solidus_api"
require "solidus_core"
require "solidus_backend"
require "solidus_support"
Expand All @@ -17,7 +18,7 @@ class Engine < ::Rails::Engine
engine_name "alchemy_solidus"

initializer "alchemy_solidus.assets", before: "alchemy.importmap" do |app|
Alchemy.admin_importmaps.add({
Alchemy.config.admin_importmaps.add({
importmap_path: root.join("config/importmap.rb"),
source_paths: [
root.join("app/javascript")
Expand Down
4 changes: 2 additions & 2 deletions spec/components/alchemy/admin/link_dialog/product_tab_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
expect(page).to have_selector("alchemy-product-select [name=product_link]")
end

it "sets the value-attribute to slug" do
expect(page).to have_selector("alchemy-product-select[value-attribute=slug]")
it "sets the value-attribute" do
expect(page).to have_selector("alchemy-product-select[value-attribute=url_path]")
end

context "with product found by url" do
Expand Down
4 changes: 2 additions & 2 deletions spec/components/alchemy/admin/product_select_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
end
end

context "with value_attribute set to evil" do
let(:value_attribute) { :evil }
context "with value_attribute set to nil" do
let(:value_attribute) { nil }

it "sets value-attribute to 'id'" do
expect(page).to have_selector(
Expand Down
4 changes: 2 additions & 2 deletions spec/features/alchemy/link_overlay_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
authorize_user admin_user

allow(element).to receive(:definition) do
{
Alchemy::ElementDefinition.new(
name: "article",
ingredients: [
{role: "headline", type: "Text", settings: {linkable: true}}
]
}
)
end

element.save!
Expand Down
32 changes: 32 additions & 0 deletions spec/models/alchemy/solidus/product_finder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require "rails_helper"

RSpec.describe Alchemy::Solidus::ProductFinder do
let(:product) { create(:product) }
let(:finder) { described_class.call(url) }

context "with url matching product slug" do
let(:url) do
Spree::Core::Engine.routes.url_helpers.product_path(product)
end

it "returns product" do
expect(finder).to eq(product)
end
end

context "with non matching url" do
let(:url) { "some/product/22" }

it "returns nil" do
expect(finder).to be_nil
end
end

context "with nil as url" do
let(:url) { nil }

it "returns nil" do
expect(finder).to be_nil
end
end
end
8 changes: 8 additions & 0 deletions spec/models/spree/product_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
RSpec.describe Spree::Product, type: :model do
it { is_expected.to have_many(:alchemy_ingredients) }

describe "#url_path" do
let(:product) { create(:product) }

it "returns the product path" do
expect(product.url_path).to eq(Spree::Core::Engine.routes.url_helpers.product_path(product))
end
end

describe "cache invalidation" do
let(:page) { create(:alchemy_page) }
let(:page_version) { create(:alchemy_page_version, page: page) }
Expand Down
2 changes: 0 additions & 2 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@
Capybara.server = :puma, {Silent: true}

RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include Alchemy::TestSupport::IntegrationHelpers, type: :feature
config.include Alchemy::TestSupport::CapybaraHelpers, type: :feature
config.include ActiveSupport::Testing::TimeHelpers, type: :model
Expand Down
4 changes: 2 additions & 2 deletions spec/views/alchemy/ingredients/spree_product_editor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

before do
allow(element).to receive(:definition) do
{
Alchemy::ElementDefinition.new(
name: "all_you_can_eat",
ingredients: [
{role: "product",
Expand All @@ -19,7 +19,7 @@
{role: "taxon",
type: "SpreeTaxon"}
]
}
)
end

allow(element_editor).to receive(:ingredients) { [Alchemy::IngredientEditor.new(ingredient)] }
Expand Down
4 changes: 2 additions & 2 deletions spec/views/alchemy/ingredients/spree_taxon_editor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

before do
allow(element).to receive(:definition) do
{
Alchemy::ElementDefinition.new(
name: "all_you_can_eat",
ingredients: [
{role: "product",
Expand All @@ -19,7 +19,7 @@
{role: "taxon",
type: "SpreeTaxon"}
]
}
)
end

allow(element_editor).to receive(:ingredients) { [Alchemy::IngredientEditor.new(ingredient)] }
Expand Down
Loading
Loading