WIP: Karol's implementation #1

Closed
stan wants to merge 23 commits from karol_master into master
72 changed files with 468 additions and 311 deletions
Showing only changes of commit de29815686 - Show all commits

14
Gemfile
View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
source 'https://rubygems.org' source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" } git_source(:github) { |repo| "https://github.com/#{repo}.git" }
@ -32,12 +34,14 @@ gem 'jquery-rails'
# Reduces boot times through caching; required in config/boot.rb # Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false gem 'bootsnap', '>= 1.4.4', require: false
gem 'rubocop', require: false
group :development, :test do group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console # Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'byebug', platforms: %i[mri mingw x64_mingw]
gem 'rspec'
gem 'rspec-rails', ">= 2.0.0.beta"
gem 'rails-controller-testing' gem 'rails-controller-testing'
gem 'rspec'
gem 'rspec-rails', '>= 2.0.0.beta'
end end
group :development do group :development do
@ -45,8 +49,8 @@ group :development do
gem 'web-console', '>= 4.1.0' gem 'web-console', '>= 4.1.0'
# Display performance information such as SQL time and flame graphs for each request in your browser. # Display performance information such as SQL time and flame graphs for each request in your browser.
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
gem 'rack-mini-profiler', '~> 2.0'
gem 'listen', '~> 3.3' gem 'listen', '~> 3.3'
gem 'rack-mini-profiler', '~> 2.0'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring' gem 'spring'
end end
@ -60,4 +64,4 @@ group :test do
end end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

View file

@ -62,6 +62,7 @@ GEM
zeitwerk (~> 2.3) zeitwerk (~> 2.3)
addressable (2.7.0) addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2)
autoprefixer-rails (10.2.4.0) autoprefixer-rails (10.2.4.0)
execjs execjs
bcrypt (3.1.16) bcrypt (3.1.16)
@ -117,6 +118,9 @@ GEM
nokogiri (1.11.2) nokogiri (1.11.2)
mini_portile2 (~> 2.5.0) mini_portile2 (~> 2.5.0)
racc (~> 1.4) racc (~> 1.4)
parallel (1.20.1)
parser (3.0.0.0)
ast (~> 2.4.1)
public_suffix (4.0.6) public_suffix (4.0.6)
puma (5.2.2) puma (5.2.2)
nio4r (~> 2.0) nio4r (~> 2.0)
@ -158,11 +162,13 @@ GEM
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (~> 1.0) thor (~> 1.0)
rainbow (3.0.0)
rake (13.0.3) rake (13.0.3)
rb-fsevent (0.10.4) rb-fsevent (0.10.4)
rb-inotify (0.10.1) rb-inotify (0.10.1)
ffi (~> 1.0) ffi (~> 1.0)
regexp_parser (2.1.1) regexp_parser (2.1.1)
rexml (3.2.4)
rspec (3.10.0) rspec (3.10.0)
rspec-core (~> 3.10.0) rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0) rspec-expectations (~> 3.10.0)
@ -184,6 +190,18 @@ GEM
rspec-mocks (~> 3.10) rspec-mocks (~> 3.10)
rspec-support (~> 3.10) rspec-support (~> 3.10)
rspec-support (3.10.2) rspec-support (3.10.2)
rubocop (1.11.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.2.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.4.1)
parser (>= 2.7.1.5)
ruby-progressbar (1.11.0)
rubyzip (2.3.0) rubyzip (2.3.0)
sass-rails (6.0.0) sass-rails (6.0.0)
sassc-rails (~> 2.1, >= 2.1.1) sassc-rails (~> 2.1, >= 2.1.1)
@ -215,6 +233,7 @@ GEM
turbolinks-source (5.2.0) turbolinks-source (5.2.0)
tzinfo (2.0.4) tzinfo (2.0.4)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
unicode-display_width (2.0.0)
web-console (4.1.0) web-console (4.1.0)
actionview (>= 6.0.0) actionview (>= 6.0.0)
activemodel (>= 6.0.0) activemodel (>= 6.0.0)
@ -254,6 +273,7 @@ DEPENDENCIES
rails-controller-testing rails-controller-testing
rspec rspec
rspec-rails (>= 2.0.0.beta) rspec-rails (>= 2.0.0.beta)
rubocop
sass-rails (>= 6) sass-rails (>= 6)
selenium-webdriver selenium-webdriver
spring spring

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
# Add your own tasks in files placed in lib/tasks ending in .rake, # Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative "config/application" require_relative 'config/application'
Rails.application.load_tasks Rails.application.load_tasks

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
module ApplicationCable module ApplicationCable
class Channel < ActionCable::Channel::Base class Channel < ActionCable::Channel::Base
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
module ApplicationCable module ApplicationCable
class Connection < ActionCable::Connection::Base class Connection < ActionCable::Connection::Base
end end

View file

@ -1,3 +1,6 @@
# frozen_string_literal: true
# Base for application controllers
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
helper_method :current_user helper_method :current_user
helper_method :logged_in? helper_method :logged_in?
@ -13,15 +16,13 @@ class ApplicationController < ActionController::Base
protected protected
def notices_from_errors(record) def notices_from_errors(record)
messages = record.errors.messages.map do |attribute, messages| errors = record.errors.messages.map do |attribute, messages|
messages.map { |message| "#{attribute} #{message}".capitalize } messages.map { |message| "#{attribute} #{message}".capitalize }
end end
messages.flatten errors.flatten
end end
def ensure_admin def ensure_admin
unless current_user&.admin? redirect_to '/welcome', notice: 'You are not allowed to perform this action' unless current_user&.admin?
redirect_to '/welcome', notice: 'You are not allowed to perform this action'
end
end end
end end

View file

@ -1,6 +1,9 @@
# frozen_string_literal: true
# Authors controller
class AuthorsController < ApplicationController class AuthorsController < ApplicationController
before_action :ensure_admin before_action :ensure_admin
before_action :set_author, only: [:edit, :update] before_action :set_author, only: %i[edit update]
def index def index
@authors = Author.all @authors = Author.all
@ -11,9 +14,7 @@ class AuthorsController < ApplicationController
end end
def update def update
if @author.update(author_params) redirect_to '/authors' if @author.update(author_params)
redirect_to '/authors'
end
end end
private private

View file

@ -1,26 +1,25 @@
# frozen_string_literal: true
# Books controller
class BooksController < ApplicationController class BooksController < ApplicationController
before_action :set_book, only: [:show, :edit, :update, :add_to_cart] before_action :set_book, only: %i[show edit update add_to_cart]
before_action :ensure_admin, only: [:edit, :update] before_action :ensure_admin, only: %i[edit update]
def index def index
if current_user&.admin? books = if current_user&.admin?
books = Book.all Book.all
else else
books = Book.published Book.published
end end
@books = books.map { |book| BooksPresenter.new(book) } @books = books.map { |book| BooksPresenter.new(book) }
end end
def show def show; end
end
def edit def edit; end
end
def update def update
if @book.update(book_params) redirect_to '/books' if @book.update(book_params)
redirect_to '/books'
end
end end
def add_to_cart def add_to_cart

View file

@ -1,30 +1,36 @@
# frozen_string_literal: true
# Sessions controller
class SessionsController < ApplicationController class SessionsController < ApplicationController
def new def new; end
end
def create def create
@user = User.find_by(email: params[:email]) @user = User.find_by(email: params[:email])
unless @user problem = problem_with_login
redirect_to '/welcome', notice: 'Wrong email address' if problem
return redirect_to '/welcome', notice: problem
end else
unless @user.authenticate(params[:password])
redirect_to '/welcome', notice: 'Wrong password'
return
end
if @user.blocked?
redirect_to '/welcome', notice: 'You are blocked, please contact support'
return
end
session[:user_id] = @user.id session[:user_id] = @user.id
redirect_to '/welcome' redirect_to '/welcome'
end end
end
def delete def delete
session.delete(:user_id) session.delete(:user_id)
redirect_to '/welcome', notice: 'Logged out properly' redirect_to '/welcome', notice: 'Logged out properly'
end end
def welcome def welcome; end
private
def problem_with_login
if !@user
'Wrong email address'
elsif !@user.authenticate(params[:password])
'Wrong password'
elsif @user.blocked?
'You are blocked, please contact support'
end
end end
end end

View file

@ -1,5 +1,8 @@
# frozen_string_literal: true
# Users controller
class UsersController < ApplicationController class UsersController < ApplicationController
before_action :ensure_admin, only: [:destroy, :block] before_action :ensure_admin, only: %i[destroy block]
def index def index
@users = User.all @users = User.all
@ -21,15 +24,14 @@ class UsersController < ApplicationController
def password_recovery_request def password_recovery_request
@user = User.where(email: params['email']).first @user = User.where(email: params['email']).first
recovery_password = ('a'..'z').to_a.shuffle[0,8].join recovery_password = ('a'..'z').to_a.sample(8).join
@user.recovery_password = recovery_password @user.recovery_password = recovery_password
@user.save @user.save
UserMailer.with(user: @user, recovery_password: recovery_password).password_recovery.deliver_now UserMailer.with(user: @user, recovery_password: recovery_password).password_recovery.deliver_now
redirect_to '/welcome', notice: "Recovery email sent to #{params['email']}" redirect_to '/welcome', notice: "Recovery email sent to #{params['email']}"
end end
def password_recovery_request_form def password_recovery_request_form; end
end
def recover_password_form def recover_password_form
@recovery_password = params[:recovery_password] @recovery_password = params[:recovery_password]

View file

@ -1,2 +1,4 @@
# frozen_string_literal: true
module ApplicationHelper module ApplicationHelper
end end

View file

@ -1,7 +1,10 @@
# frozen_string_literal: true
module BooksHelper module BooksHelper
def cart_summary def cart_summary
number_to_currency(@books.map{ |b| b.price }.reduce(:+)) number_to_currency(@books.map(&:price).reduce(:+))
end end
def can_book_be_added?(book) def can_book_be_added?(book)
logged_in? && book.quantity.positive? && !current_user.books.exists?(book.id) logged_in? && book.quantity.positive? && !current_user.books.exists?(book.id)
end end

View file

@ -1,2 +1,4 @@
# frozen_string_literal: true
module SessionsHelper module SessionsHelper
end end

View file

@ -1,2 +1,4 @@
# frozen_string_literal: true
module UsersHelper module UsersHelper
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ApplicationJob < ActiveJob::Base class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock # Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked # retry_on ActiveRecord::Deadlocked

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com' default from: 'from@example.com'
layout 'mailer' layout 'mailer'

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class UserMailer < ApplicationMailer class UserMailer < ApplicationMailer
def password_recovery def password_recovery
@user = params[:user] @user = params[:user]

View file

@ -1,23 +1,28 @@
# frozen_string_literal: true
class ApplicationRecord < ActiveRecord::Base class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true self.abstract_class = true
def update(*args) def update(*args)
result = super(*args) result = super(*args)
AuditRecord.create(model: self.class, action: 'update', params: self.to_json) AuditRecord.create(model: self.class, action: 'update', params: to_json)
result result
end end
def save(*args) def save(*args)
result = super(*args) result = super(*args)
AuditRecord.create(model: self.class, action: 'save', params: self.to_json) AuditRecord.create(model: self.class, action: 'save', params: to_json)
result result
end end
def self.create(*args) def self.create(*args)
result = super(*args) result = super(*args)
AuditRecord.create(model: self.class, action: 'create', params: result.to_json) AuditRecord.create(model: self.class, action: 'create', params: result.to_json)
result result
end end
def decrement!(*args) def decrement!(*args)
result = super(*args) result = super(*args)
AuditRecord.create(model: self.class, action: 'decrement!', params: self.to_json) AuditRecord.create(model: self.class, action: 'decrement!', params: to_json)
result result
end end
end end

View file

@ -1,2 +1,4 @@
# frozen_string_literal: true
class AuditRecord < ActiveRecord::Base class AuditRecord < ActiveRecord::Base
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Author < ApplicationRecord class Author < ApplicationRecord
validates :first_name, presence: true validates :first_name, presence: true
validates :last_name, presence: true validates :last_name, presence: true

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Book < ApplicationRecord class Book < ApplicationRecord
has_and_belongs_to_many :authors has_and_belongs_to_many :authors

View file

@ -1,10 +1,12 @@
# frozen_string_literal: true
class User < ApplicationRecord class User < ApplicationRecord
has_and_belongs_to_many :books has_and_belongs_to_many :books
has_secure_password has_secure_password
has_secure_password :recovery_password, validations: false has_secure_password :recovery_password, validations: false
enum role: [:customer, :admin], _default: :customer enum role: %i[customer admin], _default: :customer
enum status: [:ready, :blocked], _default: :ready enum status: %i[ready blocked], _default: :ready
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP } validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :role, presence: true validates :role, presence: true
@ -12,6 +14,6 @@ class User < ApplicationRecord
validates :password, { validates :password, {
presence: true, presence: true,
length: { minimum: 8 }, length: { minimum: 8 },
if: lambda{ new_record? || !password.nil? } if: -> { new_record? || !password.nil? }
} }
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class BooksPresenter < SimpleDelegator class BooksPresenter < SimpleDelegator
include ActiveSupport::NumberHelper include ActiveSupport::NumberHelper

View file

@ -8,46 +8,46 @@
# this file is here to facilitate running it. # this file is here to facilitate running it.
# #
require "rubygems" require 'rubygems'
m = Module.new do m = Module.new do
module_function module_function
def invoked_as_script? def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__) File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
end end
def env_var_version def env_var_version
ENV["BUNDLER_VERSION"] ENV['BUNDLER_VERSION']
end end
def cli_arg_version def cli_arg_version
return unless invoked_as_script? # don't want to hijack other binstubs return unless invoked_as_script? # don't want to hijack other binstubs
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` return unless 'update'.start_with?(ARGV.first || ' ') # must be running `bundle update`
bundler_version = nil bundler_version = nil
update_index = nil update_index = nil
ARGV.each_with_index do |a, i| ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN bundler_version = a if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1
bundler_version = Regexp.last_match(1)
update_index = i update_index = i
end end
bundler_version bundler_version
end end
def gemfile def gemfile
gemfile = ENV["BUNDLE_GEMFILE"] gemfile = ENV['BUNDLE_GEMFILE']
return gemfile if gemfile && !gemfile.empty? return gemfile if gemfile && !gemfile.empty?
File.expand_path("../../Gemfile", __FILE__) File.expand_path('../Gemfile', __dir__)
end end
def lockfile def lockfile
lockfile = lockfile =
case File.basename(gemfile) case File.basename(gemfile)
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) when 'gems.rb' then gemfile.sub(/\.rb$/, gemfile)
else "#{gemfile}.lock" else "#{gemfile}.lock"
end end
File.expand_path(lockfile) File.expand_path(lockfile)
@ -55,8 +55,10 @@ m = Module.new do
def lockfile_version def lockfile_version
return unless File.file?(lockfile) return unless File.file?(lockfile)
lockfile_contents = File.read(lockfile) lockfile_contents = File.read(lockfile)
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
Regexp.last_match(1) Regexp.last_match(1)
end end
@ -73,28 +75,32 @@ m = Module.new do
requirement = bundler_gem_version.approximate_recommendation requirement = bundler_gem_version.approximate_recommendation
return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0") return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new('2.7.0')
requirement += ".a" if bundler_gem_version.prerelease? requirement += '.a' if bundler_gem_version.prerelease?
requirement requirement
end end
def load_bundler! def load_bundler!
ENV["BUNDLE_GEMFILE"] ||= gemfile ENV['BUNDLE_GEMFILE'] ||= gemfile
activate_bundler activate_bundler
end end
def activate_bundler def activate_bundler
gem_error = activation_error_handling do gem_error = activation_error_handling do
gem "bundler", bundler_requirement gem 'bundler', bundler_requirement
end end
return if gem_error.nil? return if gem_error.nil?
require_error = activation_error_handling do require_error = activation_error_handling do
require "bundler/version" require 'bundler/version'
end end
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
return
end
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
exit 42 exit 42
end end
@ -109,6 +115,4 @@ end
m.load_bundler! m.load_bundler!
if m.invoked_as_script? load Gem.bin_path('bundler', 'bundle') if m.invoked_as_script?
load Gem.bin_path("bundler", "bundle")
end

View file

@ -1,5 +1,7 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
load File.expand_path("spring", __dir__) # frozen_string_literal: true
load File.expand_path('spring', __dir__)
APP_PATH = File.expand_path('../config/application', __dir__) APP_PATH = File.expand_path('../config/application', __dir__)
require_relative "../config/boot" require_relative '../config/boot'
require "rails/commands" require 'rails/commands'

View file

@ -1,5 +1,7 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
load File.expand_path("spring", __dir__) # frozen_string_literal: true
require_relative "../config/boot"
require "rake" load File.expand_path('spring', __dir__)
require_relative '../config/boot'
require 'rake'
Rake.application.run Rake.application.run

View file

@ -1,5 +1,7 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require "fileutils" # frozen_string_literal: true
require 'fileutils'
# path to your application root. # path to your application root.
APP_ROOT = File.expand_path('..', __dir__) APP_ROOT = File.expand_path('..', __dir__)

View file

@ -1,13 +1,15 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"]) # frozen_string_literal: true
gem "bundler"
require "bundler" if !defined?(Spring) && [nil, 'development', 'test'].include?(ENV['RAILS_ENV'])
gem 'bundler'
require 'bundler'
# Load Spring without loading other gems in the Gemfile, for speed. # Load Spring without loading other gems in the Gemfile, for speed.
Bundler.locked_gems&.specs&.find { |spec| spec.name == "spring" }&.tap do |spring| Bundler.locked_gems&.specs&.find { |spec| spec.name == 'spring' }&.tap do |spring|
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
gem "spring", spring.version gem 'spring', spring.version
require "spring/binstub" require 'spring/binstub'
rescue Gem::LoadError rescue Gem::LoadError
# Ignore when Spring is not installed. # Ignore when Spring is not installed.
end end

View file

@ -1,18 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# frozen_string_literal: true
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
ENV["NODE_ENV"] ||= "development" ENV['NODE_ENV'] ||= 'development'
require "pathname" require 'pathname'
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
Pathname.new(__FILE__).realpath) Pathname.new(__FILE__).realpath)
require "bundler/setup" require 'bundler/setup'
require "webpacker" require 'webpacker'
require "webpacker/webpack_runner" require 'webpacker/webpack_runner'
APP_ROOT = File.expand_path("..", __dir__) APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do Dir.chdir(APP_ROOT) do
Webpacker::WebpackRunner.run(ARGV) Webpacker::WebpackRunner.run(ARGV)
end end

View file

@ -1,18 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# frozen_string_literal: true
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
ENV["NODE_ENV"] ||= "development" ENV['NODE_ENV'] ||= 'development'
require "pathname" require 'pathname'
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
Pathname.new(__FILE__).realpath) Pathname.new(__FILE__).realpath)
require "bundler/setup" require 'bundler/setup'
require "webpacker" require 'webpacker'
require "webpacker/dev_server_runner" require 'webpacker/dev_server_runner'
APP_ROOT = File.expand_path("..", __dir__) APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do Dir.chdir(APP_ROOT) do
Webpacker::DevServerRunner.run(ARGV) Webpacker::DevServerRunner.run(ARGV)
end end

View file

@ -1,17 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# frozen_string_literal: true
APP_ROOT = File.expand_path('..', __dir__) APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do Dir.chdir(APP_ROOT) do
yarn = ENV["PATH"].split(File::PATH_SEPARATOR). yarn = ENV['PATH'].split(File::PATH_SEPARATOR)
select { |dir| File.expand_path(dir) != __dir__ }. .reject { |dir| File.expand_path(dir) == __dir__ }
product(["yarn", "yarn.cmd", "yarn.ps1"]). .product(['yarn', 'yarn.cmd', 'yarn.ps1'])
map { |dir, file| File.expand_path(file, dir) }. .map { |dir, file| File.expand_path(file, dir) }
find { |file| File.executable?(file) } .find { |file| File.executable?(file) }
if yarn if yarn
exec yarn, *ARGV exec yarn, *ARGV
else else
$stderr.puts "Yarn executable was not detected in the system." warn 'Yarn executable was not detected in the system.'
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" warn 'Download Yarn at https://yarnpkg.com/en/docs/install'
exit 1 exit 1
end end
end end

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
# This file is used by Rack-based servers to start the application. # This file is used by Rack-based servers to start the application.
require_relative "config/environment" require_relative 'config/environment'
run Rails.application run Rails.application
Rails.application.load_server Rails.application.load_server

View file

@ -1,6 +1,8 @@
require_relative "boot" # frozen_string_literal: true
require "rails/all" require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems # Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production. # you've limited to :test, :development, or :production.

View file

@ -1,4 +1,6 @@
# frozen_string_literal: true
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require "bundler/setup" # Set up gems listed in the Gemfile. require 'bundler/setup' # Set up gems listed in the Gemfile.
require "bootsnap/setup" # Speed up boot time by caching expensive operations. require 'bootsnap/setup' # Speed up boot time by caching expensive operations.

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true
# Load the Rails application. # Load the Rails application.
require_relative "application" require_relative 'application'
# Initialize the Rails application. # Initialize the Rails application.
Rails.application.initialize! Rails.application.initialize!

View file

@ -1,4 +1,6 @@
require "active_support/core_ext/integer/time" # frozen_string_literal: true
require 'active_support/core_ext/integer/time'
Rails.application.configure do Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb. # Settings specified here will take precedence over those in config/application.rb.

View file

@ -1,4 +1,6 @@
require "active_support/core_ext/integer/time" # frozen_string_literal: true
require 'active_support/core_ext/integer/time'
Rails.application.configure do Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb. # Settings specified here will take precedence over those in config/application.rb.
@ -88,8 +90,8 @@ Rails.application.configure do
# require "syslog/logger" # require "syslog/logger"
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present? if ENV['RAILS_LOG_TO_STDOUT'].present?
logger = ActiveSupport::Logger.new(STDOUT) logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger) config.logger = ActiveSupport::TaggedLogging.new(logger)
end end

View file

@ -1,4 +1,6 @@
require "active_support/core_ext/integer/time" # frozen_string_literal: true
require 'active_support/core_ext/integer/time'
# The test environment is used exclusively to run your application's # The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that # test suite. You never need to work with it otherwise. Remember that

View file

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# ActiveSupport::Reloader.to_prepare do # ActiveSupport::Reloader.to_prepare do

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets. # Version of your assets, change this if you want to expire all your assets.

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
@ -5,4 +7,4 @@
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] Rails.backtrace_cleaner.remove_silencers! if ENV['BACKTRACE']

View file

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Define an application-wide content security policy # Define an application-wide content security policy

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Specify a serializer for the signed and encrypted cookie jars. # Specify a serializer for the signed and encrypted cookie jars.

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file. # Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [ Rails.application.config.filter_parameters += %i[
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn passw secret token _key crypt salt certificate otp ssn
] ]

View file

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections # Add new inflection rules using the following format. Inflections

View file

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks: # Add new mime types for use in respond_to blocks:

View file

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Define an application-wide HTTP permissions policy. For further # Define an application-wide HTTP permissions policy. For further
# information see https://developers.google.com/web/updates/2018/06/feature-policy # information see https://developers.google.com/web/updates/2018/06/feature-policy
# #

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# This file contains settings for ActionController::ParamsWrapper which # This file contains settings for ActionController::ParamsWrapper which

View file

@ -1,28 +1,30 @@
# frozen_string_literal: true
# Puma can serve each request in a thread from an internal thread pool. # Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum. # The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match # Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum # the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record. # and maximum; this matches the default thread size of Active Record.
# #
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
threads min_threads_count, max_threads_count threads min_threads_count, max_threads_count
# Specifies the `worker_timeout` threshold that Puma will use to wait before # Specifies the `worker_timeout` threshold that Puma will use to wait before
# terminating a worker in development environments. # terminating a worker in development environments.
# #
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" worker_timeout 3600 if ENV.fetch('RAILS_ENV', 'development') == 'development'
# Specifies the `port` that Puma will listen on to receive requests; default is 3000. # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
# #
port ENV.fetch("PORT") { 3000 } port ENV.fetch('PORT', 3000)
# Specifies the `environment` that Puma will run in. # Specifies the `environment` that Puma will run in.
# #
environment ENV.fetch("RAILS_ENV") { "development" } environment ENV.fetch('RAILS_ENV', 'development')
# Specifies the `pidfile` that Puma will use. # Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')
# Specifies the number of `workers` to boot in clustered mode. # Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together # Workers are forked web server processes. If using threads and workers together

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
Rails.application.routes.draw do Rails.application.routes.draw do
resources :users resources :users
get 'login', to: 'sessions#new' get 'login', to: 'sessions#new'

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
Spring.watch( Spring.watch(
".ruby-version", '.ruby-version',
".rbenv-vars", '.rbenv-vars',
"tmp/restart.txt", 'tmp/restart.txt',
"tmp/caching-dev.txt" 'tmp/caching-dev.txt'
) )

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateAuthors < ActiveRecord::Migration[6.1] class CreateAuthors < ActiveRecord::Migration[6.1]
def change def change
create_table :authors do |t| create_table :authors do |t|
@ -7,6 +9,6 @@ class CreateAuthors < ActiveRecord::Migration[6.1]
t.timestamps t.timestamps
end end
add_index :authors, [ :first_name, :last_name ] add_index :authors, %i[first_name last_name]
end end
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateBooks < ActiveRecord::Migration[6.1] class CreateBooks < ActiveRecord::Migration[6.1]
def change def change
create_table :books do |t| create_table :books do |t|

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateAuthorsBooks < ActiveRecord::Migration[6.1] class CreateAuthorsBooks < ActiveRecord::Migration[6.1]
def change def change
create_table :authors_books do |t| create_table :authors_books do |t|

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateUsers < ActiveRecord::Migration[6.1] class CreateUsers < ActiveRecord::Migration[6.1]
def change def change
create_table :users do |t| create_table :users do |t|

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ChangeUsernameToEmail < ActiveRecord::Migration[6.1] class ChangeUsernameToEmail < ActiveRecord::Migration[6.1]
def change def change
rename_column :users, :username, :email rename_column :users, :username, :email

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddPasswordRecoveryCodeToUsers < ActiveRecord::Migration[6.1] class AddPasswordRecoveryCodeToUsers < ActiveRecord::Migration[6.1]
def change def change
add_column :users, :password_recovery_code, :string add_column :users, :password_recovery_code, :string

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ChangePasswordRecoveryCodeToRecoveryPasswordDigest < ActiveRecord::Migration[6.1] class ChangePasswordRecoveryCodeToRecoveryPasswordDigest < ActiveRecord::Migration[6.1]
def change def change
rename_column :users, :password_recovery_code, :recovery_password_digest rename_column :users, :password_recovery_code, :recovery_password_digest

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddRoleToUsers < ActiveRecord::Migration[6.1] class AddRoleToUsers < ActiveRecord::Migration[6.1]
def change def change
add_column :users, :role, :integer add_column :users, :role, :integer

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddStatusToUsers < ActiveRecord::Migration[6.1] class AddStatusToUsers < ActiveRecord::Migration[6.1]
def change def change
add_column :users, :status, :integer add_column :users, :status, :integer

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateAuditRecords < ActiveRecord::Migration[6.1] class CreateAuditRecords < ActiveRecord::Migration[6.1]
def change def change
create_table :audit_records do |t| create_table :audit_records do |t|

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddQuantityToBooks < ActiveRecord::Migration[6.1] class AddQuantityToBooks < ActiveRecord::Migration[6.1]
def change def change
add_column :books, :quantity, :integer add_column :books, :quantity, :integer

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateBooksUsers < ActiveRecord::Migration[6.1] class CreateBooksUsers < ActiveRecord::Migration[6.1]
def change def change
create_table :books_users do |t| create_table :books_users do |t|

90
db/schema.rb generated
View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# This file is auto-generated from the current state of the database. Instead # 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 # of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition. # incrementally modify your database, and then regenerate this schema definition.
@ -10,60 +12,58 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_03_22_002803) do ActiveRecord::Schema.define(version: 20_210_322_002_803) do
create_table 'audit_records', force: :cascade do |t|
create_table "audit_records", force: :cascade do |t| t.string 'model'
t.string "model" t.string 'action'
t.string "action" t.string 'params'
t.string "params" t.datetime 'created_at', precision: 6, null: false
t.datetime "created_at", precision: 6, null: false t.datetime 'updated_at', precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end end
create_table "authors", force: :cascade do |t| create_table 'authors', force: :cascade do |t|
t.string "first_name" t.string 'first_name'
t.string "last_name" t.string 'last_name'
t.datetime "created_at", precision: 6, null: false t.datetime 'created_at', precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime 'updated_at', precision: 6, null: false
t.index ["first_name", "last_name"], name: "index_authors_on_first_name_and_last_name" t.index %w[first_name last_name], name: 'index_authors_on_first_name_and_last_name'
end end
create_table "authors_books", force: :cascade do |t| create_table 'authors_books', force: :cascade do |t|
t.integer "book_id" t.integer 'book_id'
t.integer "author_id" t.integer 'author_id'
t.datetime "created_at", precision: 6, null: false t.datetime 'created_at', precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime 'updated_at', precision: 6, null: false
t.index ["author_id"], name: "index_authors_books_on_author_id" t.index ['author_id'], name: 'index_authors_books_on_author_id'
t.index ["book_id"], name: "index_authors_books_on_book_id" t.index ['book_id'], name: 'index_authors_books_on_book_id'
end end
create_table "books", force: :cascade do |t| create_table 'books', force: :cascade do |t|
t.string "title" t.string 'title'
t.decimal "price", precision: 10, scale: 2 t.decimal 'price', precision: 10, scale: 2
t.boolean "published" t.boolean 'published'
t.datetime "created_at", precision: 6, null: false t.datetime 'created_at', precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime 'updated_at', precision: 6, null: false
t.integer "quantity" t.integer 'quantity'
t.index ["published"], name: "index_books_on_published" t.index ['published'], name: 'index_books_on_published'
end end
create_table "books_users", force: :cascade do |t| create_table 'books_users', force: :cascade do |t|
t.integer "book_id" t.integer 'book_id'
t.integer "user_id" t.integer 'user_id'
t.datetime "created_at", precision: 6, null: false t.datetime 'created_at', precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime 'updated_at', precision: 6, null: false
t.index ["book_id"], name: "index_books_users_on_book_id" t.index ['book_id'], name: 'index_books_users_on_book_id'
t.index ["user_id"], name: "index_books_users_on_user_id" t.index ['user_id'], name: 'index_books_users_on_user_id'
end end
create_table "users", force: :cascade do |t| create_table 'users', force: :cascade do |t|
t.string "email" t.string 'email'
t.string "password_digest" t.string 'password_digest'
t.datetime "created_at", precision: 6, null: false t.datetime 'created_at', precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime 'updated_at', precision: 6, null: false
t.string "recovery_password_digest" t.string 'recovery_password_digest'
t.integer "role" t.integer 'role'
t.integer "status" t.integer 'status'
end end
end end

View file

@ -1,7 +1,9 @@
# frozen_string_literal: true
books = Book.create([ books = Book.create([
{ {
title: 'Journey to the Center of the Earth', title: 'Journey to the Center of the Earth',
price: 10900, price: 10_900,
published: true, published: true,
quantity: 100 quantity: 100
}, },
@ -22,7 +24,7 @@ books = Book.create([
price: 3700, price: 3700,
published: true, published: true,
quantity: 5 quantity: 5
}, }
]) ])
authors = Author.create([ authors = Author.create([
@ -32,7 +34,7 @@ authors = Author.create([
}, },
{ {
first_name: 'Dick', first_name: 'Dick',
last_name: 'Pick', last_name: 'Pick'
}, },
{ {
first_name: 'Rick', first_name: 'Rick',
@ -41,7 +43,7 @@ authors = Author.create([
{ {
first_name: 'Alan', first_name: 'Alan',
last_name: 'Milne' last_name: 'Milne'
}, }
]) ])
books.first.authors << authors.first books.first.authors << authors.first
@ -68,5 +70,5 @@ User.create([
password: 'aaaaaaaa', password: 'aaaaaaaa',
role: :customer, role: :customer,
status: :ready status: :ready
}, }
]) ])

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe ApplicationController do RSpec.describe ApplicationController do

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe SessionsController do RSpec.describe SessionsController do
@ -8,14 +10,14 @@ RSpec.describe SessionsController do
end end
end end
describe 'get create' do describe 'get create' do
# TODO test session status # TODO: test session status
subject { get 'create' } subject { get 'create' }
it 'redirects to /welcome' do it 'redirects to /welcome' do
expect(subject).to redirect_to('/welcome') expect(subject).to redirect_to('/welcome')
end end
end end
describe 'get delete' do describe 'get delete' do
# TODO test session status # TODO: test session status
subject { get 'delete' } subject { get 'delete' }
it 'redirects to /welcome' do it 'redirects to /welcome' do
expect(subject).to redirect_to('/welcome') expect(subject).to redirect_to('/welcome')

View file

@ -1,7 +1,9 @@
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe UsersController do RSpec.describe UsersController do
before(:all) do # TODO change it to cleanup after each test before(:all) do # TODO: change it to cleanup after each test
User.destroy_all User.destroy_all
end end
let(:user1) do let(:user1) do
@ -40,7 +42,7 @@ RSpec.describe UsersController do
srand(10) srand(10)
subject subject
email_text = ActionMailer::Base.deliveries.last.body.raw_source email_text = ActionMailer::Base.deliveries.last.body.raw_source
expect(email_text).to match("recover_password/#{user1.id}/tfohbclx") expect(email_text).to match("recover_password/#{user1.id}/jeravuxl")
end end
it 'sends a recovery email to the proper email' do it 'sends a recovery email to the proper email' do
subject subject

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true
# Preview all emails at http://localhost:3000/rails/mailers/user # Preview all emails at http://localhost:3000/rails/mailers/user
class UserMailerPreview < ActionMailer::Preview class UserMailerPreview < ActionMailer::Preview
end end

View file

@ -1,4 +1,6 @@
require "rails_helper" # frozen_string_literal: true
require 'rails_helper'
RSpec.describe UserMailer, type: :mailer do RSpec.describe UserMailer, type: :mailer do
# TODO # TODO

View file

@ -1,9 +1,11 @@
# frozen_string_literal: true
# This file is copied to spec/ when you run 'rails generate rspec:install' # This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper' require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test' ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__) require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production # Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production? abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'rspec/rails' require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point! # Add additional requires below this line. Rails is not loaded until this point!

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# This file was generated by the `rails generate rspec:install` command. Conventionally, all # This file was generated by the `rails generate rspec:install` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause # The generated `.rspec` file contains `--require spec_helper` which will cause
@ -46,51 +48,49 @@ RSpec.configure do |config|
# The settings below are suggested to provide a good initial experience # The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content. # with RSpec, but feel free to customize to your heart's content.
=begin # # This allows you to limit a spec run to individual examples or groups
# This allows you to limit a spec run to individual examples or groups # # you care about by tagging them with `:focus` metadata. When nothing
# you care about by tagging them with `:focus` metadata. When nothing # # is tagged with `:focus`, all examples get run. RSpec also provides
# is tagged with `:focus`, all examples get run. RSpec also provides # # aliases for `it`, `describe`, and `context` that include `:focus`
# aliases for `it`, `describe`, and `context` that include `:focus` # # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
# metadata: `fit`, `fdescribe` and `fcontext`, respectively. # config.filter_run_when_matching :focus
config.filter_run_when_matching :focus #
# # Allows RSpec to persist some state between runs in order to support
# Allows RSpec to persist some state between runs in order to support # # the `--only-failures` and `--next-failure` CLI options. We recommend
# the `--only-failures` and `--next-failure` CLI options. We recommend # # you configure your source control system to ignore this file.
# you configure your source control system to ignore this file. # config.example_status_persistence_file_path = "spec/examples.txt"
config.example_status_persistence_file_path = "spec/examples.txt" #
# # Limits the available syntax to the non-monkey patched syntax that is
# Limits the available syntax to the non-monkey patched syntax that is # # recommended. For more details, see:
# recommended. For more details, see: # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode # config.disable_monkey_patching!
config.disable_monkey_patching! #
# # Many RSpec users commonly either run the entire suite or an individual
# Many RSpec users commonly either run the entire suite or an individual # # file, and it's useful to allow more verbose output when running an
# file, and it's useful to allow more verbose output when running an # # individual spec file.
# individual spec file. # if config.files_to_run.one?
if config.files_to_run.one? # # Use the documentation formatter for detailed output,
# Use the documentation formatter for detailed output, # # unless a formatter has already been configured
# unless a formatter has already been configured # # (e.g. via a command-line flag).
# (e.g. via a command-line flag). # config.default_formatter = "doc"
config.default_formatter = "doc" # end
end #
# # Print the 10 slowest examples and example groups at the
# Print the 10 slowest examples and example groups at the # # end of the spec run, to help surface which specs are running
# end of the spec run, to help surface which specs are running # # particularly slow.
# particularly slow. # config.profile_examples = 10
config.profile_examples = 10 #
# # Run specs in random order to surface order dependencies. If you find an
# Run specs in random order to surface order dependencies. If you find an # # order dependency and want to debug it, you can fix the order by providing
# order dependency and want to debug it, you can fix the order by providing # # the seed, which is printed after each run.
# the seed, which is printed after each run. # # --seed 1234
# --seed 1234 # config.order = :random
config.order = :random #
# # Seed global randomization in this process using the `--seed` CLI option.
# Seed global randomization in this process using the `--seed` CLI option. # # Setting this allows you to use `--seed` to deterministically reproduce
# Setting this allows you to use `--seed` to deterministically reproduce # # test failures related to randomization by passing the same `--seed` value
# test failures related to randomization by passing the same `--seed` value # # as the one that triggered the failure.
# as the one that triggered the failure. # Kernel.srand config.seed
Kernel.srand config.seed
=end
end end