diff --git a/.rubocop.yml b/.rubocop.yml index 74285f4..859f2b7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.7 # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop # to ignore them, so only the ones explicitly set in this file are enabled. DisabledByDefault: true @@ -11,17 +11,15 @@ AllCops: - 'db/**/*' - 'config/**/*' - 'vendor/**/*' + - 'test/**/*' + - 'bin/**/*' + - 'Rakefile' + NewCops: enable # Prefer &&/|| over and/or. Style/AndOr: Enabled: true -# Do not use braces for hash literals when they are the last argument of a -# method call. -Style/BracesAroundHashParameters: - Enabled: true - EnforcedStyle: context_dependent - # Align `when` with `case`. Layout/CaseIndentation: Enabled: true @@ -59,7 +57,6 @@ Style/HashSyntax: # extra level of indentation. Layout/IndentationConsistency: Enabled: true - EnforcedStyle: rails # Two spaces, no tabs (for indentation). Layout/IndentationWidth: @@ -109,14 +106,13 @@ Layout/SpaceInsideParens: # Check quotes usage according to lint rule below. Style/StringLiterals: Enabled: true - EnforcedStyle: double_quotes # Detect hard tabs, no hard tabs. -Layout/Tab: +Layout/IndentationStyle: Enabled: true # Blank lines should not have any spaces. -Layout/TrailingBlankLines: +Layout/TrailingEmptyLines: Enabled: true # No trailing whitespace. @@ -124,7 +120,7 @@ Layout/TrailingWhitespace: Enabled: true # Use quotes for string literals when they are enough. -Style/UnneededPercentQ: +Style/RedundantPercentQ: Enabled: true # Align `end` with the matching keyword or starting expression except for @@ -144,6 +140,8 @@ Metrics/LineLength: # Prefer the compact readable style Style/ClassAndModuleChildren: EnforcedStyle: compact + Exclude: + - 'lib/generators/abraham/install_generator.rb' Style/FormatStringToken: EnforcedStyle: template diff --git a/.ruby-version b/.ruby-version index aedc15b..2c9b4ef 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.3 +2.7.3 diff --git a/Gemfile b/Gemfile index 43849c9..6615044 100644 --- a/Gemfile +++ b/Gemfile @@ -1,9 +1,6 @@ # frozen_string_literal: true -source 'http://rubygems.org' -group :development, :test do - gem 'sassc-rails' -end +source 'http://rubygems.org' # Set the Rails version. We have this switch so that we can test multiple # versions for Rails on Travis CI. @@ -13,7 +10,7 @@ rails = case rails_version when 'default' '~> 5.2' when 'master' - {github: 'rails/rails'} + { github: 'rails/rails' } else "~> #{rails_version}" end diff --git a/README.md b/README.md index 0b395e2..06bc83e 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,12 @@ Install the JavaScript dependencies: $ yarn add js-cookie@^2.2.0 shepherd.js@^6.0.0-beta ``` +Mount the engine in `config/routes.rb`. It is important to mount Abraham as `abraham`, since the inserted `abraham_tour` partial (below) leverages an isolated named route. + +``` +mount Abraham::Engine, at: 'abraham' +``` + Require `abraham` in `app/assets/javascripts/application.js` ``` @@ -68,10 +74,13 @@ defaults: &defaults You can also [write your own Shepherd theme](https://shepherdjs.dev/docs/tutorial-03-styling.html) based on Shepherd's [default CSS](https://github.com/shipshapecode/shepherd/releases/download/v6.0.0-beta.1/shepherd.css). -Tell Abraham where to insert its generated JavaScript in `app/views/layouts/application.html.erb`, just before the closing `body` tag: +Tell Abraham where to insert the JavaScript partial. This partial sets up the [Shepherd JS](https://shepherdjs.dev/) tour/s. + +Generally it is inserted in `app/views/layouts/application.html.erb`, just before the closing `body` tag: ```erb <%= abraham_tour %> + ``` @@ -250,7 +259,12 @@ Use `bundle info [gemname]` to see where a bundled gem is installed. #### Testing locally -This Rails engine contains a test app called `dummy` with controller and system tests. They'll all get run with `rails t`. +This Rails engine contains a test app called `dummy` with controller and system tests. You can run tests by: + +``` +~ rake app:assets:precompile +~ rails test +``` Please note that if you change anything in the `lib/generators` folder (i.e. configuration, intializer, migration) you'll need to migrate the `dummy` app accordingly. diff --git a/abraham.gemspec b/abraham.gemspec index 65c6fb8..295f6f8 100644 --- a/abraham.gemspec +++ b/abraham.gemspec @@ -1,22 +1,22 @@ # frozen_string_literal: true -$LOAD_PATH.push File.expand_path("lib", __dir__) +$LOAD_PATH.push File.expand_path('lib', __dir__) # Maintain your gem's version: -require "abraham/version" +require 'abraham/version' # Describe your gem and declare its dependencies: Gem::Specification.new do |s| - s.name = "abraham" + s.name = 'abraham' s.version = Abraham::VERSION - s.authors = ["Jonathan Abbett"] - s.email = ["jonathan@act.md"] - s.homepage = "https://github.com/actmd/abraham" - s.summary = "Trackable application tours for Rails with i18n support, based on Shepherd.js." - s.description = "Trackable application tours for Rails with i18n support, based on Shepherd.js." - s.license = "MIT" + s.authors = ['Jonathan Abbett'] + s.email = ['jonathan@act.md'] + s.homepage = 'https://github.com/actmd/abraham' + s.summary = 'Trackable application tours for Rails with i18n support, based on Shepherd.js.' + s.description = 'Trackable application tours for Rails with i18n support, based on Shepherd.js.' + s.license = 'MIT' - s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"] + s.files = Dir['{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.md'] s.add_development_dependency 'sassc-rails' s.add_development_dependency 'sqlite3' diff --git a/app/controllers/abraham/histories_controller.rb b/app/controllers/abraham/histories_controller.rb new file mode 100644 index 0000000..03ab033 --- /dev/null +++ b/app/controllers/abraham/histories_controller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class Abraham::HistoriesController < ApplicationController + def create + abraham_history = Abraham::History.new(abraham_history_params).tap do |history| + history.creator_id = current_user.id + end + + respond_to do |format| + if abraham_history.save + format.json { render json: abraham_history, status: :created } + else + format.json { render json: abraham_history.errors, status: :unprocessable_entity } + end + end + end + + private + + def abraham_history_params + params.require(:history).permit(:controller_name, :action_name, :tour_name) + end +end diff --git a/app/controllers/abraham_histories_controller.rb b/app/controllers/abraham_histories_controller.rb deleted file mode 100644 index 0b76042..0000000 --- a/app/controllers/abraham_histories_controller.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -class AbrahamHistoriesController < ApplicationController - def create - @abraham_history = AbrahamHistory.new(abraham_history_params) - @abraham_history.creator_id = current_user.id - respond_to do |format| - if @abraham_history.save - format.json { render json: @abraham_history, status: :created } - else - format.json { render json: @abraham_history.errors, status: :unprocessable_entity } - end - end - end - - private - - def abraham_history_params - params.require(:abraham_history).permit(:controller_name, :action_name, :tour_name) - end -end diff --git a/app/helpers/abraham_helper.rb b/app/helpers/abraham_helper.rb index 7d4db7b..583c3d3 100644 --- a/app/helpers/abraham_helper.rb +++ b/app/helpers/abraham_helper.rb @@ -9,7 +9,7 @@ def abraham_tour if tours # Have any automatic tours been completed already? - completed = AbrahamHistory.where( + completed = Abraham::History.where( creator_id: current_user.id, controller_name: controller_path, action_name: action_name @@ -21,11 +21,11 @@ def abraham_tour tour_html = '' tour_keys.each do |key| - tour_html += render(partial: "application/abraham", - locals: { tour_name: key, - tour_completed: tour_keys_completed.include?(key), - trigger: tours[key]["trigger"], - steps: tours[key]["steps"] }) + tour_html += render(partial: 'application/abraham', + locals: { tour_name: key, + tour_completed: tour_keys_completed.include?(key), + trigger: tours[key]['trigger'], + steps: tours[key]['steps'] }) end tour_html.html_safe diff --git a/app/models/application_record.rb b/app/models/abraham/application_record.rb similarity index 54% rename from app/models/application_record.rb rename to app/models/abraham/application_record.rb index 71fbba5..73ce7e1 100644 --- a/app/models/application_record.rb +++ b/app/models/abraham/application_record.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -class ApplicationRecord < ActiveRecord::Base +class Abraham::ApplicationRecord < ActiveRecord::Base self.abstract_class = true end diff --git a/app/models/abraham/history.rb b/app/models/abraham/history.rb new file mode 100644 index 0000000..593bc44 --- /dev/null +++ b/app/models/abraham/history.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +class Abraham::History < ApplicationRecord +end diff --git a/app/models/abraham_history.rb b/app/models/abraham_history.rb deleted file mode 100644 index b400a14..0000000 --- a/app/models/abraham_history.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class AbrahamHistory < ActiveRecord::Base -end diff --git a/app/views/application/_abraham.html.erb b/app/views/application/_abraham.html.erb index 51d24b4..937be2d 100644 --- a/app/views/application/_abraham.html.erb +++ b/app/views/application/_abraham.html.erb @@ -4,7 +4,7 @@ <% if trigger != 'manual' %> Abraham.tours["<%= tour_name %>"].on("complete", function() { // Make AJAX call to save history of tour completion - return fetch("/abraham_histories/", { + return fetch('<%= abraham.histories_path %>', { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ diff --git a/config/routes.rb b/config/routes.rb index bda83df..5cf0bcd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -Rails.application.routes.draw do - resources :abraham_histories, only: :create +Abraham::Engine.routes.draw do + resources :histories, only: :create end diff --git a/lib/abraham.rb b/lib/abraham.rb index d413b79..11084d5 100644 --- a/lib/abraham.rb +++ b/lib/abraham.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "abraham/engine" +require 'abraham/engine' module Abraham end diff --git a/lib/abraham/engine.rb b/lib/abraham/engine.rb index 9234726..5cd06d3 100644 --- a/lib/abraham/engine.rb +++ b/lib/abraham/engine.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true -require "rubygems" +class Abraham::Engine < ::Rails::Engine + isolate_namespace Abraham -module Abraham - class Engine < ::Rails::Engine + ActiveSupport.on_load(:action_controller_base) do + helper AbrahamHelper end end diff --git a/lib/abraham/version.rb b/lib/abraham/version.rb index e3afab7..47e9f50 100644 --- a/lib/abraham/version.rb +++ b/lib/abraham/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Abraham - VERSION = "2.4.0" + VERSION = '2.4.0' end diff --git a/lib/generators/abraham/install_generator.rb b/lib/generators/abraham/install_generator.rb index 03ee440..f97cd3c 100644 --- a/lib/generators/abraham/install_generator.rb +++ b/lib/generators/abraham/install_generator.rb @@ -1,36 +1,36 @@ # frozen_string_literal: true -require "rails/generators" -require "rails/generators/active_record" +require 'rails/generators' +require 'rails/generators/active_record' module Abraham module Generators class InstallGenerator < ActiveRecord::Generators::Base - argument :name, type: :string, default: "random_name" + argument :name, type: :string, default: 'random_name' class_option :'skip-migration', type: :boolean, desc: "Don't generate a migration for the histories table" class_option :'skip-initializer', type: :boolean, desc: "Don't generate an initializer" class_option :'skip-config', type: :boolean, desc: "Don't generate a config file" - source_root File.expand_path(File.join(File.dirname(__FILE__), "templates")) + source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates')) # Copies the migration template to db/migrate. def copy_files - return if options["skip-migration"] + return if options['skip-migration'] - migration_template "migration.rb", "db/migrate/create_abraham_histories.rb" + migration_template 'migration.rb', 'db/migrate/create_abraham_histories.rb' end def create_initializer - return if options["skip-initializer"] + return if options['skip-initializer'] - copy_file "initializer.rb", "config/initializers/abraham.rb" + copy_file 'initializer.rb', 'config/initializers/abraham.rb' end def create_config - return if options["skip-config"] + return if options['skip-config'] - copy_file "abraham.yml", "config/abraham.yml" + copy_file 'abraham.yml', 'config/abraham.yml' end end end diff --git a/test/dummy/config/routes.rb b/test/dummy/config/routes.rb index cebcb7a..6c8664a 100644 --- a/test/dummy/config/routes.rb +++ b/test/dummy/config/routes.rb @@ -10,5 +10,7 @@ get "dashboard/home" end + mount Abraham::Engine, at: 'abraham' + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end diff --git a/test/dummy/test/controllers/abraham/histories_controller_test.rb b/test/dummy/test/controllers/abraham/histories_controller_test.rb new file mode 100644 index 0000000..71ae857 --- /dev/null +++ b/test/dummy/test/controllers/abraham/histories_controller_test.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'test_helper' + +module Abraham + class HistoriesControllerTest < ActionDispatch::IntegrationTest + test 'creates Abraham::History' do + assert_difference ['Abraham::History.count'] do + post abraham.histories_url, as: :json, params: { history: { action_name: 'foo', controller_name: 'bar', tour_name: 'baz' } } + end + end + end +end diff --git a/test/dummy/test/controllers/abraham_histories_controller_test.rb b/test/dummy/test/controllers/abraham_histories_controller_test.rb deleted file mode 100644 index 1b1b374..0000000 --- a/test/dummy/test/controllers/abraham_histories_controller_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -require "test_helper" - -class AbrahamHistoriesControllerTest < ActionDispatch::IntegrationTest - test "should create AbrahamHistory" do - assert_difference ["AbrahamHistory.count"] do - post abraham_histories_url, as: :json, params: { abraham_history: { action_name: "foo", controller_name: "bar", tour_name: "baz" } } - end - end -end