Fully functioning, ready for code review.

This commit is contained in:
Jonathan Abbett 2016-11-21 16:01:27 -05:00
parent 55a510bac0
commit 3849d72de9
40 changed files with 4236 additions and 59 deletions

1
.gitignore vendored
View File

@ -42,3 +42,4 @@ bower.json
.byebug_history .byebug_history
.idea/ .idea/
/test/dummy/tmp/

View File

@ -1 +1 @@
2.3.1 2.3.2

View File

@ -2,8 +2,10 @@ PATH
remote: . remote: .
specs: specs:
abraham (0.1.0) abraham (0.1.0)
jquery-rails
rails (~> 5.0.0, >= 5.0.0.1) rails (~> 5.0.0, >= 5.0.0.1)
rails-assets-shepherd.js (~> 1.8) rails-assets-shepherd.js (~> 1.8)
sass-rails (~> 5.0)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
@ -53,6 +55,10 @@ GEM
globalid (0.3.7) globalid (0.3.7)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
i18n (0.7.0) i18n (0.7.0)
jquery-rails (4.2.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
loofah (2.0.3) loofah (2.0.3)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.6.4) mail (2.6.4)
@ -96,6 +102,13 @@ GEM
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rake (11.3.0) rake (11.3.0)
sass (3.4.22)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sprockets (3.7.0) sprockets (3.7.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
@ -106,6 +119,7 @@ GEM
sqlite3 (1.3.12) sqlite3 (1.3.12)
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (2.0.5)
tzinfo (1.2.2) tzinfo (1.2.2)
thread_safe (~> 0.1) thread_safe (~> 0.1)
websocket-driver (0.6.4) websocket-driver (0.6.4)

View File

@ -17,8 +17,10 @@ Gem::Specification.new do |s|
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_dependency "rails", "~> 5.0.0", ">= 5.0.0.1" s.add_dependency "rails", "~> 5.0.0", ">= 5.0.0.1"
s.add_dependency 'sass-rails', '~> 5.0'
s.add_dependency "rails-assets-shepherd.js", "~> 1.8"
s.add_development_dependency "sqlite3" s.add_development_dependency "sqlite3"
s.add_runtime_dependency "rails-assets-shepherd.js", "~> 1.8" s.add_runtime_dependency 'jquery-rails'
end end

View File

@ -1,9 +1,10 @@
class AbrahamHistoriesController < ApplicationController class AbrahamHistoriesController < ApplicationController
def create def create
@abraham_history = AbrahamHistory.new(abraham_history_params) @abraham_history = AbrahamHistory.new(abraham_history_params)
@abraham_history.creator_id = current_user
respond_to do |format| respond_to do |format|
if @abraham_history.save if @abraham_history.save
format.json { render :show, status: :created, location: @abraham_history } format.json { render json: @abraham_history, status: :created }
else else
format.json { render json: @abraham_history.errors, status: :unprocessable_entity } format.json { render json: @abraham_history.errors, status: :unprocessable_entity }
end end

View File

@ -1,22 +1,22 @@
module AbrahamHelper module AbrahamHelper
def abraham_tour def abraham_tour
# Do we have tours for this controller/action in the user's locale? # Do we have tours for this controller/action in the user's locale?
tours = Rails.configuration.abraham["#{controller_name}.#{action_name}.#{I18n.locale}"] tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"]
unless tours unless tours
# How about the default locale? # How about the default locale?
tours = Rails.configuration.abraham["#{controller_name}.#{action_name}.#{I18n.default_locale}"] tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
end end
if tours if tours
completed = AbrahamHistory.where( completed = AbrahamHistory.where(
creator: @current_person, controller_name: controller_name, creator_id: current_user, controller_name: controller_name,
action_name: action_name) action_name: action_name)
remaining = tours.keys - completed.map(&:tour_name) remaining = tours.keys - completed.map(&:tour_name)
if remaining.any? if remaining.any?
# Generate the javascript snippet for the next remaining tour # Generate the javascript snippet for the next remaining tour
render(:partial => 'application/tour', render(:partial => 'application/abraham',
:locals => {:tour_name => remaining.first, :locals => {:tour_name => remaining.first,
:steps => tours[remaining.first]['steps']}) :steps => tours[remaining.first]['steps']})
end end

View File

@ -1,8 +1,7 @@
<script> <script>
var tour = new Shepherd.Tour({ var tour = new Shepherd.Tour({
defaults: { defaults: {
// TODO In abraham, this should be configurable classes: '<%= Rails.configuration.abraham.default_theme %>'
classes: 'shepherd-theme-default'
} }
}); });

View File

@ -1,2 +1,3 @@
Rails.application.routes.draw do Rails.application.routes.draw do
resources :abraham_histories, only: :create
end end

View File

@ -1,5 +1,4 @@
require "abraham/engine" require 'abraham/engine'
module Abraham module Abraham
# Your code goes here...
end end

View File

@ -1,3 +1,7 @@
require 'rubygems'
require 'rails-assets-shepherd.js'
require 'jquery-rails'
module Abraham module Abraham
class Engine < ::Rails::Engine class Engine < ::Rails::Engine
end end

View File

@ -0,0 +1,26 @@
require 'rails/generators'
require "rails/generators/active_record"
module Abraham
module Generators
class InstallGenerator < ActiveRecord::Generators::Base
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"
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']
migration_template 'migration.rb', 'db/migrate/create_abraham_histories.rb'
end
def create_initializer
return if options['skip-initializer']
copy_file 'initializer.rb', 'config/initializers/abraham.rb'
end
end
end
end

View File

@ -15,5 +15,6 @@ Rails.application.configure do
end end
end end
config.abraham = tours config.abraham.default_theme = 'shepherd-theme-default'
config.abraham.tours = tours
end end

View File

@ -0,0 +1,12 @@
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
def change
create_table :abraham_histories do |t|
t.string :controller_name
t.string :action_name
t.string :tour_name
t.references :creator, null: false, index: true
t.timestamps index: true
end
end
end

View File

@ -1,22 +0,0 @@
require 'rails/generators'
require "rails/generators/active_record"
class AbrahamGenerator < ActiveRecord::Generators::Base
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"
source_root File.expand_path('../../abraham', __FILE__)
# Copies the migration template to db/migrate.
def copy_files
return if options['skip-migration']
migration_template 'migration.rb', 'db/migrate/create_abraham_histories.rb'
end
def create_initializer
return if options['skip-initializer']
copy_file 'initializer.rb', 'config/initializers/abraham.rb'
end
end

View File

@ -10,4 +10,8 @@
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives. // about supported directives.
// //
//= require jquery
//= require jquery_ujs
//= require tether
//= require shepherd.js.js
//= require_tree . //= require_tree .

View File

@ -0,0 +1,2 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

View File

@ -10,6 +10,6 @@
* files in this directory. Styles in this file should be added after the last require_* statement. * files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope. * It is generally better to create a new file per style scope.
* *
*= require "shepherd.js/dist/css/shepherd-theme-default"
*= require_tree . *= require_tree .
*= require_self
*/ */

View File

@ -0,0 +1,4 @@
/*
Place all the styles related to the matching controller here.
They will automatically be included in application.css.
*/

View File

@ -1,3 +1,8 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery with: :exception protect_from_forgery with: :exception
helper_method :current_user
def current_user
SecureRandom.uuid
end
end end

View File

@ -0,0 +1,7 @@
class DashboardController < ApplicationController
def home
end
def other
end
end

View File

@ -0,0 +1,2 @@
module DashboardHelper
end

View File

@ -0,0 +1,6 @@
<h1>Dashboard#home</h1>
<p>Find me in app/views/dashboard/home.html.erb</p>
<div class="notice-me" style="width:300px;height:300px;background-color:whitesmoke;">
a content element to notice
</div>

View File

@ -0,0 +1,2 @@
<h1>Dashboard#other</h1>
<p>Find me in app/views/dashboard/other.html.erb</p>

View File

@ -10,5 +10,7 @@
<body> <body>
<%= yield %> <%= yield %>
<%= abraham_tour %>
</body> </body>
</html> </html>

View File

@ -0,0 +1,21 @@
Rails.application.configure do
tours = {}
if Rails.root.join('config/tours').exist?
Dir[Rails.root.join('config/tours/*/')].each do |dir|
Dir[dir + '*.yml'].each do |yml|
path_parts = yml.split(File::SEPARATOR)
controller = path_parts[path_parts.size - 2]
file_parts = path_parts[path_parts.size - 1].split('.')
action = file_parts[0]
locale = file_parts[1]
t = YAML.load_file(yml)
tours["#{controller}.#{action}.#{locale}"] = t
end
end
end
config.abraham = ActiveSupport::OrderedOptions.new
config.abraham.default_theme = 'shepherd-theme-default'
config.abraham.tours = tours
end

View File

@ -1,3 +1,7 @@
Rails.application.routes.draw do Rails.application.routes.draw do
get 'dashboard/home'
get 'dashboard/other'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end end

View File

@ -0,0 +1,13 @@
intro:
steps:
1:
text: "ENGLISH This first HOME step is centered text-only"
2:
title: "ENGLISH This step has a title"
text: "ENGLISH This intermediate step has some text"
3:
title: "ENGLISH The final step"
text: "ENGLISH Some text here too, and it's attached to the right"
attachTo:
element: ".notice-me"
position: "right"

View File

@ -0,0 +1,13 @@
intro:
steps:
1:
text: "SPANISH This first HOME step is centered text-only"
2:
title: "SPANISH This step has a title"
text: "This intermediate step has some text"
3:
title: "SPANISH The final step"
text: "Some text here too, and it's attached to the right"
attachTo:
element: ".notice-me"
position: "right"

View File

@ -0,0 +1,11 @@
tour_one:
steps:
1:
title: "TOUR ONE step one ENGLISH"
text: "we show this on your first visit"
tour_two:
steps:
1:
title: "TOUR TWO step one ENGLISH"
text: "we show this on your second visit"

Binary file not shown.

View File

@ -0,0 +1,12 @@
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
def change
create_table :abraham_histories do |t|
t.string :controller_name
t.string :action_name
t.string :tour_name
t.references :creator, null: false, index: true
t.timestamps index: true
end
end
end

27
test/dummy/db/schema.rb Normal file
View File

@ -0,0 +1,27 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161118143752) do
create_table "abraham_histories", force: :cascade do |t|
t.string "controller_name"
t.string "action_name"
t.string "tour_name"
t.integer "creator_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["created_at"], name: "index_abraham_histories_on_created_at"
t.index ["creator_id"], name: "index_abraham_histories_on_creator_id"
t.index ["updated_at"], name: "index_abraham_histories_on_updated_at"
end
end

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
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

View File

@ -0,0 +1,55 @@
require 'test_helper'
class DashboardControllerTest < ActionDispatch::IntegrationTest
test "uses configured shepherd theme" do
# default
get dashboard_home_url
assert_response :success
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "classes: 'shepherd-theme-default'"
end
# custom
Rails.configuration.abraham.default_theme = "my-custom-theme"
get dashboard_home_url
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "classes: 'my-custom-theme'"
end
end
test "home should have home tour code" do
get dashboard_home_url
assert_response :success
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "ENGLISH This first HOME step is centered text-only"
# it has three steps
assert element.text.include? "step-1"
assert element.text.include? "step-2"
assert element.text.include? "step-3"
# it will post the right completion information
assert element.text.include? "controller_name: 'dashboard'"
assert element.text.include? "action_name: 'home'"
assert element.text.include? "tour_name: 'intro'"
end
end
test "other should have other tour code" do
get dashboard_other_url
assert_response :success
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "TOUR ONE step one ENGLISH"
# it has only one steps
assert element.text.include? "step-1"
# it will post the right completion information
assert element.text.include? "controller_name: 'dashboard'"
assert element.text.include? "action_name: 'other'"
assert element.text.include? "tour_name: 'tour_one'"
end
end
end

View File

@ -1,11 +0,0 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
controller_name: MyString
action_name: MyString
tour_name: MyString
one:
controller_name: MyString
action_name: MyString
tour_name: MyString

View File

@ -1,10 +1,10 @@
require 'test_helper' require 'test_helper'
require "rails/generators" require "rails/generators"
require "generators/abraham_generator" require "generators/abraham/install_generator"
class AbrahamGeneratorTest < Rails::Generators::TestCase class InstallGeneratorTest < Rails::Generators::TestCase
tests AbrahamGenerator tests Abraham::Generators::InstallGenerator
destination File.expand_path("../../tmp", __FILE__) destination File.expand_path("../../tmp", __FILE__)
setup :prepare_destination setup :prepare_destination

View File

@ -8,12 +8,3 @@ require "rails/test_help"
# Filter out Minitest backtrace while allowing backtrace from other libraries # Filter out Minitest backtrace while allowing backtrace from other libraries
# to be shown. # to be shown.
Minitest.backtrace_filter = Minitest::BacktraceFilter.new Minitest.backtrace_filter = Minitest::BacktraceFilter.new
# Load fixtures from the engine
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
ActiveSupport::TestCase.fixtures :all
end