diff --git a/.circleci/config.yml b/.circleci/config.yml index 7deedd7..2fd7722 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,31 +1,52 @@ version: 2.1 orbs: + # Required for feature specs. + browser-tools: circleci/browser-tools@1.1 + # Always take the latest version of the orb, this allows us to # run specs against Solidus supported versions only without the need # to change this configuration every time a Solidus version is released # or goes EOL. solidusio_extensions: solidusio/extensions@volatile - browser-tools: circleci/browser-tools@1.1 - jobs: + run-specs-with-sqlite: + executor: + name: solidusio_extensions/sqlite + ruby_version: "3.0" + steps: + - browser-tools/install-chrome + - solidusio_extensions/run-tests run-specs-with-postgres: - executor: solidusio_extensions/postgres + executor: + name: solidusio_extensions/postgres + ruby_version: "3.0" steps: - - browser-tools/install-browser-tools + - browser-tools/install-chrome - solidusio_extensions/run-tests run-specs-with-mysql: - executor: solidusio_extensions/mysql + executor: + name: solidusio_extensions/mysql + ruby_version: "3.0" steps: - - browser-tools/install-browser-tools + - browser-tools/install-chrome - solidusio_extensions/run-tests + lint-code: + executor: + name: solidusio_extensions/sqlite-memory + ruby_version: "3.0" + steps: + - solidusio_extensions/lint-code workflows: "Run specs on supported Solidus versions": jobs: + - run-specs-with-sqlite - run-specs-with-postgres - run-specs-with-mysql + - lint-code + "Weekly run specs against master": triggers: - schedule: @@ -35,5 +56,6 @@ workflows: only: - master jobs: + - run-specs-with-sqlite - run-specs-with-postgres - run-specs-with-mysql diff --git a/.github/stale.yml b/.github/stale.yml index d9f6563..0d0b1c9 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,17 +1 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 60 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 7 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security -# Label to use when marking an issue as stale -staleLabel: wontfix -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false \ No newline at end of file +_extends: .github diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000..eac0962 --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,2 @@ +issues=false +exclude-labels=infrastructure diff --git a/.gitignore b/.gitignore index bcd4aea..753f083 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,7 @@ pkg *.swp spec/dummy spec/examples.txt +Gemfile-local +/sandbox +.rvmrc +.ruby-gemset diff --git a/.rubocop.yml b/.rubocop.yml index 6207a64..ed101eb 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,2 +1,7 @@ +inherit_from: .rubocop_todo.yml + require: - solidus_dev_support/rubocop + +AllCops: + NewCops: disable diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..5079dfa --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,11 @@ +Layout/ArgumentAlignment: + Enabled: false + +RSpec/DescribeClass: + Enabled: false + +Style/MissingRespondToMissing: + Enabled: false + +Style/ClassAndModuleChildren: + Enabled: false diff --git a/Gemfile b/Gemfile index 69a2b47..d9777fb 100644 --- a/Gemfile +++ b/Gemfile @@ -3,14 +3,17 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -branch = ENV.fetch('SOLIDUS_BRANCH', 'master') -solidus_git, solidus_frontend_git = if (branch == 'master') || (branch >= 'v3.2') - %w[solidusio/solidus solidusio/solidus_frontend] - else - %w[solidusio/solidus] * 2 - end -gem 'solidus', github: solidus_git, branch: branch -gem 'solidus_frontend', github: solidus_frontend_git, branch: branch +branch = ENV.fetch('SOLIDUS_BRANCH', 'main') +gem 'solidus', github: 'solidusio/solidus', branch: branch + +# The solidus_frontend gem has been pulled out since v3.2 +if branch >= 'v3.2' + gem 'solidus_frontend' +elsif branch == 'main' + gem 'solidus_frontend', github: 'solidusio/solidus_frontend', branch: branch +else + gem 'solidus_frontend', github: 'solidusio/solidus', branch: branch +end # Needed to help Bundler figure out how to resolve dependencies, # otherwise it takes forever to resolve them. @@ -20,7 +23,7 @@ gem 'rails', '>0.a' # Provides basic authentication functionality for testing parts of your engine gem 'solidus_auth_devise' -case ENV['DB'] +case ENV.fetch('DB', nil) when 'mysql' gem 'mysql2' when 'postgresql' @@ -29,8 +32,16 @@ else gem 'sqlite3' end +# While we still support Ruby < 3 we need to workaround a limitation in +# the 'async' gem that relies on the latest ruby, since RubyGems doesn't +# resolve gems based on the required ruby version. +gem 'async', '< 3' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3') + gemspec # Use a local Gemfile to include development dependencies that might not be -# relevant for the project or for other contributors, e.g.: `gem 'pry-debug'`. -eval_gemfile 'Gemfile-local' if File.exist? 'Gemfile-local' +# relevant for the project or for other contributors, e.g. pry-byebug. +# +# We use `send` instead of calling `eval_gemfile` to work around an issue with +# how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658. +send(:eval_gemfile, 'Gemfile-local') if File.exist? 'Gemfile-local' diff --git a/Rakefile b/Rakefile index c08aa46..4e3773f 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'bundler/gem_tasks' require 'solidus_dev_support/rake_tasks' SolidusDevSupport::RakeTasks.install diff --git a/app/decorators/controllers/solidus_print_invoice/spree/admin/orders_controller_decorator.rb b/app/decorators/controllers/solidus_print_invoice/spree/admin/orders_controller_decorator.rb index f874a69..3190a32 100644 --- a/app/decorators/controllers/solidus_print_invoice/spree/admin/orders_controller_decorator.rb +++ b/app/decorators/controllers/solidus_print_invoice/spree/admin/orders_controller_decorator.rb @@ -16,9 +16,11 @@ def show respond_with(@order) do |format| format.pdf do template = params[:template] || "invoice" - if (template == "invoice") && ::Spree::PrintInvoice::Config.use_sequential_number? && @order.invoice_number.blank? + if (template == "invoice") && + ::Spree::PrintInvoice::Config.use_sequential_number? && + @order.invoice_number.blank? @order.invoice_number = ::Spree::PrintInvoice::Config.increase_invoice_number - @order.invoice_date = Date.today + @order.invoice_date = Time.zone.today @order.save! end render layout: false, template: "spree/admin/orders/#{template}", formats: [:pdf], handlers: [:prawn] diff --git a/app/helpers/spree/admin/print_invoice_helper.rb b/app/helpers/spree/admin/print_invoice_helper.rb index 92812e4..95ec423 100644 --- a/app/helpers/spree/admin/print_invoice_helper.rb +++ b/app/helpers/spree/admin/print_invoice_helper.rb @@ -4,7 +4,9 @@ module Spree module Admin module PrintInvoiceHelper def font_faces - fonts = Prawn::Font::AFM::BUILT_INS.reject { |f| f =~ /zapf|symbol|bold|italic|oblique/i }.map { |f| [f.tr('-', ' '), f] } + fonts = Prawn::Font::AFM::BUILT_INS.reject do |f| + f =~ /zapf|symbol|bold|italic|oblique/i + end.map { |f| [f.tr('-', ' '), f] } options_for_select(fonts, Spree::PrintInvoice::Config[:print_invoice_font_face]) end diff --git a/app/models/spree/print_invoice_configuration.rb b/app/models/spree/print_invoice_configuration.rb index faffc8d..4cc6040 100644 --- a/app/models/spree/print_invoice_configuration.rb +++ b/app/models/spree/print_invoice_configuration.rb @@ -14,7 +14,7 @@ class PrintInvoiceConfiguration < Preferences::Configuration 'logo/solidus_logo.png' else Spree::Config[:admin_interface_logo] - end + end preference :print_invoice_logo_scale, :integer, default: 50 preference :print_invoice_font_face, :string, default: 'Helvetica' diff --git a/bin/rails b/bin/rails index c535fd2..6dbbbc3 100755 --- a/bin/rails +++ b/bin/rails @@ -1,15 +1,7 @@ #!/usr/bin/env ruby -# frozen_string_literal: true - -app_root = 'spec/dummy' - -unless File.exist? "#{app_root}/bin/rails" - system "bin/rake", app_root or begin # rubocop:disable Style/AndOr - warn "Automatic creation of the dummy app failed" - exit 1 - end +if %w[g generate].include? ARGV.first + exec "#{__dir__}/rails-engine", *ARGV +else + exec "#{__dir__}/rails-sandbox", *ARGV end - -Dir.chdir app_root -exec 'bin/rails', *ARGV diff --git a/bin/rails-engine b/bin/rails-engine new file mode 100755 index 0000000..8ff0cae --- /dev/null +++ b/bin/rails-engine @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails gems +# installed from the root of your application. + +ENGINE_ROOT = File.expand_path('..', __dir__) +ENGINE_PATH = File.expand_path('../lib/solidus_print_invoice/engine', __dir__) + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) + +require 'rails/all' +require 'rails/engine/commands' diff --git a/bin/rails-sandbox b/bin/rails-sandbox new file mode 100755 index 0000000..ad2df04 --- /dev/null +++ b/bin/rails-sandbox @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby + +app_root = 'sandbox' + +unless File.exist? "#{app_root}/bin/rails" + warn 'Creating the sandbox app...' + Dir.chdir "#{__dir__}/.." do + system "#{__dir__}/sandbox" or begin + warn 'Automatic creation of the sandbox app failed' + exit 1 + end + end +end + +Dir.chdir app_root +exec 'bin/rails', *ARGV diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..836ad3b --- /dev/null +++ b/bin/rake @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rake', 'rake') diff --git a/bin/sandbox b/bin/sandbox new file mode 100755 index 0000000..00ea309 --- /dev/null +++ b/bin/sandbox @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +set -e +test -z "${DEBUG+empty_string}" || set -x + +test "$DB" = "sqlite" && export DB="sqlite3" + +if [ -z "$SOLIDUS_BRANCH" ] +then + echo "~~> Use 'export SOLIDUS_BRANCH=[main|v3.2|...]' to control the Solidus branch" + SOLIDUS_BRANCH="main" +fi +echo "~~> Using branch $SOLIDUS_BRANCH of solidus" + +if [ -z "$SOLIDUS_FRONTEND" ] +then + echo "~~> Use 'export SOLIDUS_FRONTEND=[solidus_frontend|solidus_starter_frontend]' to control the Solidus frontend" + SOLIDUS_FRONTEND="solidus_frontend" +fi +echo "~~> Using branch $SOLIDUS_FRONTEND as the solidus frontend" + +extension_name="solidus_print_invoice" + +# Stay away from the bundler env of the containing extension. +function unbundled { + ruby -rbundler -e'b = proc {system *ARGV}; Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env(&b) : Bundler.with_clean_env(&b)' -- $@ +} + +rm -rf ./sandbox +unbundled bundle exec rails new sandbox \ + --database="${DB:-sqlite3}" \ + --skip-bundle \ + --skip-git \ + --skip-keeps \ + --skip-rc \ + --skip-spring \ + --skip-test \ + --skip-javascript + +if [ ! -d "sandbox" ]; then + echo 'sandbox rails application failed' + exit 1 +fi + +cd ./sandbox +cat <> Gemfile +gem 'solidus', github: 'solidusio/solidus', branch: '$SOLIDUS_BRANCH' +gem 'rails-i18n' +gem 'solidus_i18n' + +gem '$extension_name', path: '..' + +group :test, :development do + platforms :mri do + gem 'pry-byebug' + end +end +RUBY + +unbundled bundle install --gemfile Gemfile + +unbundled bundle exec rake db:drop db:create + +unbundled bundle exec rails generate solidus:install \ + --auto-accept \ + --user_class=Spree::User \ + --enforce_available_locales=true \ + --with-authentication=true \ + --payment-method=none \ + --frontend=${SOLIDUS_FRONTEND} \ + $@ + +unbundled bundle exec rails generate solidus:auth:install --auto-run-migrations +unbundled bundle exec rails generate ${extension_name}:install --auto-run-migrations + +echo +echo "๐Ÿš€ Sandbox app successfully created for $extension_name!" +echo "๐Ÿงช This app is intended for test purposes." diff --git a/bin/setup b/bin/setup index 40d7811..67d9193 100755 --- a/bin/setup +++ b/bin/setup @@ -5,4 +5,4 @@ set -vx gem install bundler --conservative bundle update -bundle exec rake clobber +bin/rake clobber diff --git a/lib/generators/solidus_print_invoice/install/install_generator.rb b/lib/generators/solidus_print_invoice/install/install_generator.rb index 40746dc..3b5a2ad 100644 --- a/lib/generators/solidus_print_invoice/install/install_generator.rb +++ b/lib/generators/solidus_print_invoice/install/install_generator.rb @@ -6,15 +6,15 @@ class InstallGenerator < Rails::Generators::Base class_option :auto_run_migrations, type: :boolean, default: false def add_migrations - run 'bundle exec rake railties:install:migrations FROM=solidus_print_invoice' + run 'bin/rails railties:install:migrations FROM=solidus_print_invoice' end def run_migrations - run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) + run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) # rubocop:disable Layout/LineLength if run_migrations - run 'bundle exec rake db:migrate' + run 'bin/rails db:migrate' else - puts 'Skipping rake db:migrate, don\'t forget to run it!' # rubocop:disable Rails/Output + puts 'Skipping bin/rails db:migrate, don\'t forget to run it!' # rubocop:disable Rails/Output end end end diff --git a/lib/solidus_print_invoice.rb b/lib/solidus_print_invoice.rb index 3534ac3..1ba86a6 100755 --- a/lib/solidus_print_invoice.rb +++ b/lib/solidus_print_invoice.rb @@ -1,8 +1,5 @@ # frozen_string_literal: true -require 'solidus_core' -require 'solidus_support' - require 'solidus_print_invoice/version' require 'solidus_print_invoice/engine' diff --git a/lib/solidus_print_invoice/engine.rb b/lib/solidus_print_invoice/engine.rb index 853756a..8178661 100644 --- a/lib/solidus_print_invoice/engine.rb +++ b/lib/solidus_print_invoice/engine.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'spree/core' -require 'deface' +require 'solidus_core' +require 'solidus_support' + require_relative '../../app/models/spree/print_invoice_configuration' module SolidusPrintInvoice @@ -17,11 +18,11 @@ class Engine < Rails::Engine g.test_framework :rspec end - initializer "spree.print_invoice.environment", before: :load_config_initializers do |_app| + initializer 'spree.print_invoice.environment', before: :load_config_initializers do |_app| Spree::PrintInvoice::Config = Spree::PrintInvoiceConfiguration.new end - initializer "spree.print_invoice.mimetypes" do |_app| + initializer 'spree.print_invoice.mimetypes' do |_app| Mime::Type.register('application/pdf', :pdf) unless Mime::Type.lookup_by_extension(:pdf) end end diff --git a/lib/solidus_print_invoice/factories.rb b/lib/solidus_print_invoice/testing_support/factories.rb similarity index 100% rename from lib/solidus_print_invoice/factories.rb rename to lib/solidus_print_invoice/testing_support/factories.rb diff --git a/solidus_print_invoice.gemspec b/solidus_print_invoice.gemspec index d931fe2..0cccbae 100755 --- a/solidus_print_invoice.gemspec +++ b/solidus_print_invoice.gemspec @@ -23,21 +23,22 @@ Gem::Specification.new do |s| end s.platform = Gem::Platform::RUBY - s.required_ruby_version = '>= 2.4' + s.required_ruby_version = '>= 2.5' + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") } + + s.files = files.grep_v(%r{^(test|spec|features)/}) + s.test_files = files.grep(%r{^(test|spec|features)/}) + s.bindir = 'exe' + s.executables = files.grep(%r{^exe/}) { |f| File.basename(f) } + s.require_paths = ['lib'] - s.files = Dir.chdir(File.expand_path(__dir__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - s.test_files = Dir['spec/**/*'] - s.bindir = "exe" - s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) } - s.require_paths = ["lib"] - - s.add_dependency 'solidus_core', ['>= 2.0.0', '< 4'] - s.add_dependency 'solidus_support', '~> 0.9' - s.add_dependency 'deface' s.add_dependency 'prawn', '1.0.0' - s.add_dependency 'solidus', ['>= 1.0', '< 4'] + s.add_dependency 'solidus_core', ['>= 2.0.0', '< 5'] + s.add_dependency 'solidus_support', '~> 0.8' - s.add_development_dependency 'solidus_dev_support' + s.add_development_dependency 'rails-controller-testing' + s.add_development_dependency 'solidus_dev_support', '~> 2.7' end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 73e9fb7..1206779 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,22 +3,33 @@ # Configure Rails Environment ENV['RAILS_ENV'] = 'test' +require 'rails-controller-testing' +Rails::Controller::Testing.install + # Run Coverage report require 'solidus_dev_support/rspec/coverage' -require File.expand_path('dummy/config/environment.rb', __dir__) +# Create the dummy app if it's still missing. +dummy_env = "#{__dir__}/dummy/config/environment.rb" +system 'bin/rake extension:test_app' unless File.exist? dummy_env +require dummy_env # Requires factories and other useful helpers defined in spree_core. require 'solidus_dev_support/rspec/feature_helper' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. -Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f } +Dir["#{__dir__}/support/**/*.rb"].sort.each { |f| require f } -# Requires factories defined in lib/solidus_print_invoice/factories.rb -require 'solidus_print_invoice/factories' +# Requires factories defined in Solidus core and this extension. +# See: lib/solidus_print_invoice/testing_support/factories.rb +SolidusDevSupport::TestingSupport::Factories.load_for(SolidusPrintInvoice::Engine) RSpec.configure do |config| config.infer_spec_type_from_file_location! config.use_transactional_fixtures = false + + if Spree.solidus_gem_version < Gem::Version.new('2.11') + config.extend Spree::TestingSupport::AuthorizationHelpers::Request, type: :system + end end