diff --git a/.gitignore b/.gitignore
index 9e4cd41..44e060a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,12 @@
-_misc/
-
+*.gem
*.orig
+
+/.rspec_failures
+/Gemfile.lock
+
+/_misc/
+/coverage/
+/spec/dummy/db/*.sqlite3*
+/spec/dummy/log/
+/spec/dummy/storage/
+/spec/dummy/tmp/
diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..f3308b8
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,3 @@
+--require rails_helper
+--format documentation
+--profile
diff --git a/activeadmin_quill_editor.gemspec b/activeadmin_quill_editor.gemspec
index eb680b0..a2f3a7a 100644
--- a/activeadmin_quill_editor.gemspec
+++ b/activeadmin_quill_editor.gemspec
@@ -14,8 +14,18 @@ Gem::Specification.new do |spec|
spec.email = 'mat@blocknot.es'
spec.homepage = 'https://github.com/blocknotes/activeadmin_quill_editor'
- spec.files = `git ls-files -z`.split("\x0")
+ spec.files = Dir['{app,lib}/**/*', 'LICENSE.txt', 'Rakefile', 'README.md']
spec.require_paths = ['lib']
- spec.add_runtime_dependency 'activeadmin', '>= 1.0'
+ spec.add_runtime_dependency 'activeadmin', '~> 2.0'
+
+ spec.add_development_dependency 'activestorage', '~> 6.0.3.2'
+ spec.add_development_dependency 'capybara', '~> 3.33.0'
+ spec.add_development_dependency 'pry', '~> 0.13.1'
+ spec.add_development_dependency 'puma', '~> 4.3.5'
+ spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
+ spec.add_development_dependency 'rspec-rails', '~> 4.0.1'
+ spec.add_development_dependency 'selenium-webdriver', '~> 3.142.7'
+ spec.add_development_dependency 'simplecov', '~> 0.19.0'
+ spec.add_development_dependency 'sqlite3', '~> 1.4.2'
end
diff --git a/bin/rails b/bin/rails
new file mode 100755
index 0000000..7fd59cc
--- /dev/null
+++ b/bin/rails
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'rails' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("railties", "rails")
diff --git a/bin/rake b/bin/rake
new file mode 100755
index 0000000..9275675
--- /dev/null
+++ b/bin/rake
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'rake' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("rake", "rake")
diff --git a/bin/rspec b/bin/rspec
new file mode 100755
index 0000000..a6c7852
--- /dev/null
+++ b/bin/rspec
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'rspec' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("rspec-core", "rspec")
diff --git a/spec/dummy/.ruby-version b/spec/dummy/.ruby-version
new file mode 100644
index 0000000..bff6ce5
--- /dev/null
+++ b/spec/dummy/.ruby-version
@@ -0,0 +1 @@
+ruby-2.7.1
diff --git a/spec/dummy/.tool-versions b/spec/dummy/.tool-versions
new file mode 100644
index 0000000..1c44dd0
--- /dev/null
+++ b/spec/dummy/.tool-versions
@@ -0,0 +1 @@
+ruby 2.6.6
diff --git a/spec/dummy/Rakefile b/spec/dummy/Rakefile
new file mode 100644
index 0000000..e85f913
--- /dev/null
+++ b/spec/dummy/Rakefile
@@ -0,0 +1,6 @@
+# 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.
+
+require_relative 'config/application'
+
+Rails.application.load_tasks
diff --git a/spec/dummy/app/admin/authors.rb b/spec/dummy/app/admin/authors.rb
new file mode 100644
index 0000000..1839574
--- /dev/null
+++ b/spec/dummy/app/admin/authors.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+ActiveAdmin.register Author do
+ menu priority: 1
+
+ permit_params :name, :email, :age, :avatar, profile_attributes: %i[id description _destroy]
+
+ index do
+ selectable_column
+ id_column
+ column :name
+ column :email
+ column :created_at
+ actions
+ end
+
+ filter :name
+ filter :created_at
+
+ show do
+ attributes_table do
+ row :name
+ row :email
+ row :age
+ row :avatar do |record|
+ image_tag url_for(record.avatar), style: 'max-width:800px;max-height:500px' if record.avatar.attached?
+ end
+ row :created_at
+ row :updated_at
+ row :profile
+ end
+ active_admin_comments
+ end
+
+ form do |f|
+ f.inputs do
+ f.input :name
+ f.input :email
+ f.input :age
+ f.input :avatar,
+ as: :file,
+ hint: (object.avatar.attached? ? "Current: #{object.avatar.filename}" : nil)
+ end
+ f.has_many :profile, allow_destroy: true do |ff|
+ ff.input :description
+ end
+ f.actions
+ end
+end
diff --git a/spec/dummy/app/admin/dashboard.rb b/spec/dummy/app/admin/dashboard.rb
new file mode 100644
index 0000000..c61d14d
--- /dev/null
+++ b/spec/dummy/app/admin/dashboard.rb
@@ -0,0 +1,32 @@
+ActiveAdmin.register_page "Dashboard" do
+ menu priority: 1, label: proc { I18n.t("active_admin.dashboard") }
+
+ content title: proc { I18n.t("active_admin.dashboard") } do
+ div class: "blank_slate_container", id: "dashboard_default_message" do
+ span class: "blank_slate" do
+ span I18n.t("active_admin.dashboard_welcome.welcome")
+ small I18n.t("active_admin.dashboard_welcome.call_to_action")
+ end
+ end
+
+ # Here is an example of a simple dashboard with columns and panels.
+ #
+ # columns do
+ # column do
+ # panel "Recent Posts" do
+ # ul do
+ # Post.recent(5).map do |post|
+ # li link_to(post.title, admin_post_path(post))
+ # end
+ # end
+ # end
+ # end
+
+ # column do
+ # panel "Info" do
+ # para "Welcome to ActiveAdmin."
+ # end
+ # end
+ # end
+ end # content
+end
diff --git a/spec/dummy/app/admin/posts.rb b/spec/dummy/app/admin/posts.rb
new file mode 100644
index 0000000..3a75931
--- /dev/null
+++ b/spec/dummy/app/admin/posts.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+ActiveAdmin.register Post do
+end
diff --git a/spec/dummy/app/admin/tags.rb b/spec/dummy/app/admin/tags.rb
new file mode 100644
index 0000000..d4749f1
--- /dev/null
+++ b/spec/dummy/app/admin/tags.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+ActiveAdmin.register Tag do
+end
diff --git a/spec/dummy/app/assets/config/manifest.js b/spec/dummy/app/assets/config/manifest.js
new file mode 100644
index 0000000..a729cf5
--- /dev/null
+++ b/spec/dummy/app/assets/config/manifest.js
@@ -0,0 +1,3 @@
+//= link_tree ../images
+//= link_directory ../stylesheets .css
+// OFF link active_storage_db_manifest.js
diff --git a/spec/dummy/app/assets/images/.keep b/spec/dummy/app/assets/images/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/dummy/app/assets/javascripts/active_admin.js b/spec/dummy/app/assets/javascripts/active_admin.js
new file mode 100644
index 0000000..d2b66c5
--- /dev/null
+++ b/spec/dummy/app/assets/javascripts/active_admin.js
@@ -0,0 +1 @@
+//= require active_admin/base
diff --git a/spec/dummy/app/assets/stylesheets/active_admin.scss b/spec/dummy/app/assets/stylesheets/active_admin.scss
new file mode 100644
index 0000000..d3c61f3
--- /dev/null
+++ b/spec/dummy/app/assets/stylesheets/active_admin.scss
@@ -0,0 +1,17 @@
+// SASS variable overrides must be declared before loading up Active Admin's styles.
+//
+// To view the variables that Active Admin provides, take a look at
+// `app/assets/stylesheets/active_admin/mixins/_variables.scss` in the
+// Active Admin source.
+//
+// For example, to change the sidebar width:
+// $sidebar-width: 242px;
+
+// Active Admin's got SASS!
+@import "active_admin/mixins";
+@import "active_admin/base";
+
+// Overriding any non-variable SASS must be done after the fact.
+// For example, to change the default status-tag color:
+//
+// .status_tag { background: #6090DB; }
diff --git a/spec/dummy/app/assets/stylesheets/application.css b/spec/dummy/app/assets/stylesheets/application.css
new file mode 100644
index 0000000..0ebd7fe
--- /dev/null
+++ b/spec/dummy/app/assets/stylesheets/application.css
@@ -0,0 +1,15 @@
+/*
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
+ * 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.
+ *
+ *= require_tree .
+ *= require_self
+ */
diff --git a/spec/dummy/app/channels/application_cable/channel.rb b/spec/dummy/app/channels/application_cable/channel.rb
new file mode 100644
index 0000000..d672697
--- /dev/null
+++ b/spec/dummy/app/channels/application_cable/channel.rb
@@ -0,0 +1,4 @@
+module ApplicationCable
+ class Channel < ActionCable::Channel::Base
+ end
+end
diff --git a/spec/dummy/app/channels/application_cable/connection.rb b/spec/dummy/app/channels/application_cable/connection.rb
new file mode 100644
index 0000000..0ff5442
--- /dev/null
+++ b/spec/dummy/app/channels/application_cable/connection.rb
@@ -0,0 +1,4 @@
+module ApplicationCable
+ class Connection < ActionCable::Connection::Base
+ end
+end
diff --git a/spec/dummy/app/controllers/application_controller.rb b/spec/dummy/app/controllers/application_controller.rb
new file mode 100644
index 0000000..09705d1
--- /dev/null
+++ b/spec/dummy/app/controllers/application_controller.rb
@@ -0,0 +1,2 @@
+class ApplicationController < ActionController::Base
+end
diff --git a/spec/dummy/app/controllers/concerns/.keep b/spec/dummy/app/controllers/concerns/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/dummy/app/helpers/application_helper.rb b/spec/dummy/app/helpers/application_helper.rb
new file mode 100644
index 0000000..de6be79
--- /dev/null
+++ b/spec/dummy/app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
diff --git a/spec/dummy/app/javascript/packs/application.js b/spec/dummy/app/javascript/packs/application.js
new file mode 100644
index 0000000..67ce467
--- /dev/null
+++ b/spec/dummy/app/javascript/packs/application.js
@@ -0,0 +1,15 @@
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// compiled file. JavaScript code in this file should be added after the last require_* statement.
+//
+// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
+// about supported directives.
+//
+//= require rails-ujs
+//= require activestorage
+//= require_tree .
diff --git a/spec/dummy/app/jobs/application_job.rb b/spec/dummy/app/jobs/application_job.rb
new file mode 100644
index 0000000..d394c3d
--- /dev/null
+++ b/spec/dummy/app/jobs/application_job.rb
@@ -0,0 +1,7 @@
+class ApplicationJob < ActiveJob::Base
+ # Automatically retry jobs that encountered a deadlock
+ # retry_on ActiveRecord::Deadlocked
+
+ # Most jobs are safe to ignore if the underlying records are no longer available
+ # discard_on ActiveJob::DeserializationError
+end
diff --git a/spec/dummy/app/mailers/application_mailer.rb b/spec/dummy/app/mailers/application_mailer.rb
new file mode 100644
index 0000000..286b223
--- /dev/null
+++ b/spec/dummy/app/mailers/application_mailer.rb
@@ -0,0 +1,4 @@
+class ApplicationMailer < ActionMailer::Base
+ default from: 'from@example.com'
+ layout 'mailer'
+end
diff --git a/spec/dummy/app/models/application_record.rb b/spec/dummy/app/models/application_record.rb
new file mode 100644
index 0000000..72feb27
--- /dev/null
+++ b/spec/dummy/app/models/application_record.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+
+ scope :published, -> {}
+end
diff --git a/spec/dummy/app/models/author.rb b/spec/dummy/app/models/author.rb
new file mode 100644
index 0000000..9f26d99
--- /dev/null
+++ b/spec/dummy/app/models/author.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class Author < ApplicationRecord
+ has_many :posts
+ has_many :published_posts, -> { published }, class_name: 'Post'
+ has_many :recent_posts, -> { recents }, class_name: 'Post'
+
+ has_many :tags, through: :posts
+
+ has_one :profile, inverse_of: :author, dependent: :destroy
+
+ has_one_attached :avatar
+
+ accepts_nested_attributes_for :profile, allow_destroy: true
+
+ validates :email, format: { with: /\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\z/i, message: 'Invalid email' }
+
+ validate -> {
+ errors.add( :base, 'Invalid age' ) if !age || age.to_i % 3 == 1
+ }
+
+ def to_s
+ "#{name} (#{age})"
+ end
+end
diff --git a/spec/dummy/app/models/concerns/.keep b/spec/dummy/app/models/concerns/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/dummy/app/models/post.rb b/spec/dummy/app/models/post.rb
new file mode 100644
index 0000000..c285325
--- /dev/null
+++ b/spec/dummy/app/models/post.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class Post < ApplicationRecord
+ enum state: %i[available unavailable arriving]
+
+ belongs_to :author, inverse_of: :posts, autosave: true
+
+ has_one :author_profile, through: :author, source: :profile
+
+ has_many :post_tags, inverse_of: :post, dependent: :destroy
+ has_many :tags, through: :post_tags
+
+ validates :title, allow_blank: false, presence: true
+
+ scope :published, -> { where(published: true) }
+ scope :recents, -> { where('created_at > ?', Date.today - 8.month) }
+
+ def short_title
+ title.truncate 10
+ end
+
+ def upper_title
+ title.upcase
+ end
+end
diff --git a/spec/dummy/app/models/post_tag.rb b/spec/dummy/app/models/post_tag.rb
new file mode 100644
index 0000000..fd0c184
--- /dev/null
+++ b/spec/dummy/app/models/post_tag.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class PostTag < ApplicationRecord
+ belongs_to :post, inverse_of: :post_tags
+ belongs_to :tag, inverse_of: :post_tags
+
+ validates :post, presence: true
+ validates :tag, presence: true
+end
diff --git a/spec/dummy/app/models/profile.rb b/spec/dummy/app/models/profile.rb
new file mode 100644
index 0000000..5f48ff1
--- /dev/null
+++ b/spec/dummy/app/models/profile.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class Profile < ApplicationRecord
+ belongs_to :author, inverse_of: :profile, touch: true
+
+ def to_s
+ description
+ end
+end
diff --git a/spec/dummy/app/models/tag.rb b/spec/dummy/app/models/tag.rb
new file mode 100644
index 0000000..50a59bc
--- /dev/null
+++ b/spec/dummy/app/models/tag.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class Tag < ApplicationRecord
+ has_many :post_tags, inverse_of: :tag, dependent: :destroy
+ has_many :posts, through: :post_tags
+end
diff --git a/spec/dummy/app/views/layouts/application.html.erb b/spec/dummy/app/views/layouts/application.html.erb
new file mode 100644
index 0000000..24307d3
--- /dev/null
+++ b/spec/dummy/app/views/layouts/application.html.erb
@@ -0,0 +1,14 @@
+
+
+
+ Dummy
+ <%= csrf_meta_tags %>
+ <%= csp_meta_tag %>
+
+ <%= stylesheet_link_tag 'application', media: 'all' %>
+
+
+
+ <%= yield %>
+
+
diff --git a/spec/dummy/app/views/layouts/mailer.html.erb b/spec/dummy/app/views/layouts/mailer.html.erb
new file mode 100644
index 0000000..cbd34d2
--- /dev/null
+++ b/spec/dummy/app/views/layouts/mailer.html.erb
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ <%= yield %>
+
+
diff --git a/spec/dummy/app/views/layouts/mailer.text.erb b/spec/dummy/app/views/layouts/mailer.text.erb
new file mode 100644
index 0000000..37f0bdd
--- /dev/null
+++ b/spec/dummy/app/views/layouts/mailer.text.erb
@@ -0,0 +1 @@
+<%= yield %>
diff --git a/spec/dummy/bin/rails b/spec/dummy/bin/rails
new file mode 100755
index 0000000..0739660
--- /dev/null
+++ b/spec/dummy/bin/rails
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+APP_PATH = File.expand_path('../config/application', __dir__)
+require_relative '../config/boot'
+require 'rails/commands'
diff --git a/spec/dummy/bin/rake b/spec/dummy/bin/rake
new file mode 100755
index 0000000..1724048
--- /dev/null
+++ b/spec/dummy/bin/rake
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+require_relative '../config/boot'
+require 'rake'
+Rake.application.run
diff --git a/spec/dummy/bin/setup b/spec/dummy/bin/setup
new file mode 100755
index 0000000..0e39e8c
--- /dev/null
+++ b/spec/dummy/bin/setup
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+require 'fileutils'
+
+# path to your application root.
+APP_ROOT = File.expand_path('..', __dir__)
+
+def system!(*args)
+ system(*args) || abort("\n== Command #{args} failed ==")
+end
+
+FileUtils.chdir APP_ROOT do
+ # This script is a way to setup or update your development environment automatically.
+ # This script is idempotent, so that you can run it at anytime and get an expectable outcome.
+ # Add necessary setup steps to this file.
+
+ puts '== Installing dependencies =='
+ system! 'gem install bundler --conservative'
+ system('bundle check') || system!('bundle install')
+
+ # puts "\n== Copying sample files =="
+ # unless File.exist?('config/database.yml')
+ # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
+ # end
+
+ puts "\n== Preparing database =="
+ system! 'bin/rails db:prepare'
+
+ puts "\n== Removing old logs and tempfiles =="
+ system! 'bin/rails log:clear tmp:clear'
+
+ puts "\n== Restarting application server =="
+ system! 'bin/rails restart'
+end
diff --git a/spec/dummy/config.ru b/spec/dummy/config.ru
new file mode 100644
index 0000000..f7ba0b5
--- /dev/null
+++ b/spec/dummy/config.ru
@@ -0,0 +1,5 @@
+# This file is used by Rack-based servers to start the application.
+
+require_relative 'config/environment'
+
+run Rails.application
diff --git a/spec/dummy/config/application.rb b/spec/dummy/config/application.rb
new file mode 100644
index 0000000..05316df
--- /dev/null
+++ b/spec/dummy/config/application.rb
@@ -0,0 +1,18 @@
+require_relative 'boot'
+
+require 'rails/all'
+
+Bundler.require(*Rails.groups)
+
+module Dummy
+ class Application < Rails::Application
+ # Initialize configuration defaults for originally generated Rails version.
+ config.load_defaults 6.0
+
+ # Settings in config/environments/* take precedence over those specified here.
+ # Application configuration can go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded after loading
+ # the framework and any gems in your application.
+ end
+end
+
diff --git a/spec/dummy/config/boot.rb b/spec/dummy/config/boot.rb
new file mode 100644
index 0000000..c9aef85
--- /dev/null
+++ b/spec/dummy/config/boot.rb
@@ -0,0 +1,5 @@
+# Set up gems listed in the Gemfile.
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
+
+require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
+$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
diff --git a/spec/dummy/config/cable.yml b/spec/dummy/config/cable.yml
new file mode 100644
index 0000000..98367f8
--- /dev/null
+++ b/spec/dummy/config/cable.yml
@@ -0,0 +1,10 @@
+development:
+ adapter: async
+
+test:
+ adapter: test
+
+production:
+ adapter: redis
+ url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
+ channel_prefix: dummy_production
diff --git a/spec/dummy/config/database.yml b/spec/dummy/config/database.yml
new file mode 100644
index 0000000..febf936
--- /dev/null
+++ b/spec/dummy/config/database.yml
@@ -0,0 +1,8 @@
+default: &default
+ adapter: sqlite3
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+ timeout: 5000
+
+test:
+ <<: *default
+ database: db/test.sqlite3
diff --git a/spec/dummy/config/environment.rb b/spec/dummy/config/environment.rb
new file mode 100644
index 0000000..426333b
--- /dev/null
+++ b/spec/dummy/config/environment.rb
@@ -0,0 +1,5 @@
+# Load the Rails application.
+require_relative 'application'
+
+# Initialize the Rails application.
+Rails.application.initialize!
diff --git a/spec/dummy/config/environments/development.rb b/spec/dummy/config/environments/development.rb
new file mode 100644
index 0000000..7a352dd
--- /dev/null
+++ b/spec/dummy/config/environments/development.rb
@@ -0,0 +1,62 @@
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the web server when you make code changes.
+ config.cache_classes = false
+
+ # Do not eager load code on boot.
+ config.eager_load = false
+
+ # Show full error reports.
+ config.consider_all_requests_local = true
+
+ # Enable/disable caching. By default caching is disabled.
+ # Run rails dev:cache to toggle caching.
+ if Rails.root.join('tmp', 'caching-dev.txt').exist?
+ config.action_controller.perform_caching = true
+ config.action_controller.enable_fragment_cache_logging = true
+
+ config.cache_store = :memory_store
+ config.public_file_server.headers = {
+ 'Cache-Control' => "public, max-age=#{2.days.to_i}"
+ }
+ else
+ config.action_controller.perform_caching = false
+
+ config.cache_store = :null_store
+ end
+
+ # Store uploaded files on the local file system (see config/storage.yml for options).
+ config.active_storage.service = :local
+
+ # # Don't care if the mailer can't send.
+ # config.action_mailer.raise_delivery_errors = false
+
+ # config.action_mailer.perform_caching = false
+
+ # Print deprecation notices to the Rails logger.
+ config.active_support.deprecation = :log
+
+ # Raise an error on page load if there are pending migrations.
+ config.active_record.migration_error = :page_load
+
+ # Highlight code that triggered database queries in logs.
+ config.active_record.verbose_query_logs = true
+
+ # Debug mode disables concatenation and preprocessing of assets.
+ # This option may cause significant delays in view rendering with a large
+ # number of complex assets.
+ config.assets.debug = true
+
+ # Suppress logger output for asset requests.
+ config.assets.quiet = true
+
+ # Raises error for missing translations.
+ # config.action_view.raise_on_missing_translations = true
+
+ # Use an evented file watcher to asynchronously detect changes in source code,
+ # routes, locales, etc. This feature depends on the listen gem.
+ # config.file_watcher = ActiveSupport::EventedFileUpdateChecker
+end
diff --git a/spec/dummy/config/environments/production.rb b/spec/dummy/config/environments/production.rb
new file mode 100644
index 0000000..319166f
--- /dev/null
+++ b/spec/dummy/config/environments/production.rb
@@ -0,0 +1,112 @@
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # Code is not reloaded between requests.
+ config.cache_classes = true
+
+ # Eager load code on boot. This eager loads most of Rails and
+ # your application in memory, allowing both threaded web servers
+ # and those relying on copy on write to perform better.
+ # Rake tasks automatically ignore this option for performance.
+ config.eager_load = true
+
+ # Full error reports are disabled and caching is turned on.
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
+
+ # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
+ # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
+ # config.require_master_key = true
+
+ # Disable serving static files from the `/public` folder by default since
+ # Apache or NGINX already handles this.
+ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+
+ # Compress CSS using a preprocessor.
+ # config.assets.css_compressor = :sass
+
+ # Do not fallback to assets pipeline if a precompiled asset is missed.
+ config.assets.compile = false
+
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+ # config.action_controller.asset_host = 'http://assets.example.com'
+
+ # Specifies the header that your server uses for sending files.
+ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
+
+ # Store uploaded files on the local file system (see config/storage.yml for options).
+ config.active_storage.service = :local
+
+ # Mount Action Cable outside main process or domain.
+ # config.action_cable.mount_path = nil
+ # config.action_cable.url = 'wss://example.com/cable'
+ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
+
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+ # config.force_ssl = true
+
+ # Use the lowest log level to ensure availability of diagnostic information
+ # when problems arise.
+ config.log_level = :debug
+
+ # Prepend all log lines with the following tags.
+ config.log_tags = [ :request_id ]
+
+ # Use a different cache store in production.
+ # config.cache_store = :mem_cache_store
+
+ # Use a real queuing backend for Active Job (and separate queues per environment).
+ # config.active_job.queue_adapter = :resque
+ # config.active_job.queue_name_prefix = "dummy_production"
+
+ # config.action_mailer.perform_caching = false
+
+ # Ignore bad email addresses and do not raise email delivery errors.
+ # Set this to true and configure the email server for immediate delivery to raise delivery errors.
+ # config.action_mailer.raise_delivery_errors = false
+
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
+ # the I18n.default_locale when a translation cannot be found).
+ config.i18n.fallbacks = true
+
+ # Send deprecation notices to registered listeners.
+ config.active_support.deprecation = :notify
+
+ # Use default logging formatter so that PID and timestamp are not suppressed.
+ config.log_formatter = ::Logger::Formatter.new
+
+ # Use a different logger for distributed setups.
+ # require 'syslog/logger'
+ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
+
+ if ENV["RAILS_LOG_TO_STDOUT"].present?
+ logger = ActiveSupport::Logger.new(STDOUT)
+ logger.formatter = config.log_formatter
+ config.logger = ActiveSupport::TaggedLogging.new(logger)
+ end
+
+ # Do not dump schema after migrations.
+ config.active_record.dump_schema_after_migration = false
+
+ # Inserts middleware to perform automatic connection switching.
+ # The `database_selector` hash is used to pass options to the DatabaseSelector
+ # middleware. The `delay` is used to determine how long to wait after a write
+ # to send a subsequent read to the primary.
+ #
+ # The `database_resolver` class is used by the middleware to determine which
+ # database is appropriate to use based on the time delay.
+ #
+ # The `database_resolver_context` class is used by the middleware to set
+ # timestamps for the last write to the primary. The resolver uses the context
+ # class timestamps to determine how long to wait before reading from the
+ # replica.
+ #
+ # By default Rails will store a last write timestamp in the session. The
+ # DatabaseSelector middleware is designed as such you can define your own
+ # strategy for connection switching and pass that into the middleware through
+ # these configuration options.
+ # config.active_record.database_selector = { delay: 2.seconds }
+ # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
+ # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
+end
diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb
new file mode 100644
index 0000000..270398b
--- /dev/null
+++ b/spec/dummy/config/environments/test.rb
@@ -0,0 +1,49 @@
+# The test environment is used exclusively to run your application's
+# test suite. You never need to work with it otherwise. Remember that
+# your test database is "scratch space" for the test suite and is wiped
+# and recreated between test runs. Don't rely on the data there!
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ config.cache_classes = false
+ config.action_view.cache_template_loading = true
+
+ # Do not eager load code on boot. This avoids loading your whole application
+ # just for the purpose of running a single test. If you are using a tool that
+ # preloads Rails for running tests, you may have to set it to true.
+ config.eager_load = false
+
+ # Configure public file server for tests with Cache-Control for performance.
+ config.public_file_server.enabled = true
+ config.public_file_server.headers = {
+ 'Cache-Control' => "public, max-age=#{1.hour.to_i}"
+ }
+
+ # Show full error reports and disable caching.
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+ config.cache_store = :null_store
+
+ # Raise exceptions instead of rendering exception templates.
+ config.action_dispatch.show_exceptions = false
+
+ # Disable request forgery protection in test environment.
+ config.action_controller.allow_forgery_protection = false
+
+ # Store uploaded files on the local file system in a temporary directory.
+ config.active_storage.service = :test
+
+ # config.action_mailer.perform_caching = false
+
+ # Tell Action Mailer not to deliver emails to the real world.
+ # The :test delivery method accumulates sent emails in the
+ # ActionMailer::Base.deliveries array.
+ # config.action_mailer.delivery_method = :test
+
+ # Print deprecation notices to the stderr.
+ config.active_support.deprecation = :stderr
+
+ # Raises error for missing translations.
+ # config.action_view.raise_on_missing_translations = true
+end
diff --git a/spec/dummy/config/initializers/active_admin.rb b/spec/dummy/config/initializers/active_admin.rb
new file mode 100644
index 0000000..92ef9e7
--- /dev/null
+++ b/spec/dummy/config/initializers/active_admin.rb
@@ -0,0 +1,335 @@
+ActiveAdmin.setup do |config|
+ # == Site Title
+ #
+ # Set the title that is displayed on the main layout
+ # for each of the active admin pages.
+ #
+ config.site_title = "Dummy"
+
+ # Set the link url for the title. For example, to take
+ # users to your main site. Defaults to no link.
+ #
+ # config.site_title_link = "/"
+
+ # Set an optional image to be displayed for the header
+ # instead of a string (overrides :site_title)
+ #
+ # Note: Aim for an image that's 21px high so it fits in the header.
+ #
+ # config.site_title_image = "logo.png"
+
+ # == Default Namespace
+ #
+ # Set the default namespace each administration resource
+ # will be added to.
+ #
+ # eg:
+ # config.default_namespace = :hello_world
+ #
+ # This will create resources in the HelloWorld module and
+ # will namespace routes to /hello_world/*
+ #
+ # To set no namespace by default, use:
+ # config.default_namespace = false
+ #
+ # Default:
+ # config.default_namespace = :admin
+ #
+ # You can customize the settings for each namespace by using
+ # a namespace block. For example, to change the site title
+ # within a namespace:
+ #
+ # config.namespace :admin do |admin|
+ # admin.site_title = "Custom Admin Title"
+ # end
+ #
+ # This will ONLY change the title for the admin section. Other
+ # namespaces will continue to use the main "site_title" configuration.
+
+ # == User Authentication
+ #
+ # Active Admin will automatically call an authentication
+ # method in a before filter of all controller actions to
+ # ensure that there is a currently logged in admin user.
+ #
+ # This setting changes the method which Active Admin calls
+ # within the application controller.
+ # config.authentication_method = :authenticate_admin_user!
+
+ # == User Authorization
+ #
+ # Active Admin will automatically call an authorization
+ # method in a before filter of all controller actions to
+ # ensure that there is a user with proper rights. You can use
+ # CanCanAdapter or make your own. Please refer to documentation.
+ # config.authorization_adapter = ActiveAdmin::CanCanAdapter
+
+ # In case you prefer Pundit over other solutions you can here pass
+ # the name of default policy class. This policy will be used in every
+ # case when Pundit is unable to find suitable policy.
+ # config.pundit_default_policy = "MyDefaultPunditPolicy"
+
+ # If you wish to maintain a separate set of Pundit policies for admin
+ # resources, you may set a namespace here that Pundit will search
+ # within when looking for a resource's policy.
+ # config.pundit_policy_namespace = :admin
+
+ # You can customize your CanCan Ability class name here.
+ # config.cancan_ability_class = "Ability"
+
+ # You can specify a method to be called on unauthorized access.
+ # This is necessary in order to prevent a redirect loop which happens
+ # because, by default, user gets redirected to Dashboard. If user
+ # doesn't have access to Dashboard, he'll end up in a redirect loop.
+ # Method provided here should be defined in application_controller.rb.
+ # config.on_unauthorized_access = :access_denied
+
+ # == Current User
+ #
+ # Active Admin will associate actions with the current
+ # user performing them.
+ #
+ # This setting changes the method which Active Admin calls
+ # (within the application controller) to return the currently logged in user.
+ # config.current_user_method = :current_admin_user
+
+ # == Logging Out
+ #
+ # Active Admin displays a logout link on each screen. These
+ # settings configure the location and method used for the link.
+ #
+ # This setting changes the path where the link points to. If it's
+ # a string, the strings is used as the path. If it's a Symbol, we
+ # will call the method to return the path.
+ #
+ # Default:
+ config.logout_link_path = :destroy_admin_user_session_path
+
+ # This setting changes the http method used when rendering the
+ # link. For example :get, :delete, :put, etc..
+ #
+ # Default:
+ # config.logout_link_method = :get
+
+ # == Root
+ #
+ # Set the action to call for the root path. You can set different
+ # roots for each namespace.
+ #
+ # Default:
+ # config.root_to = 'dashboard#index'
+
+ # == Admin Comments
+ #
+ # This allows your users to comment on any resource registered with Active Admin.
+ #
+ # You can completely disable comments:
+ # config.comments = false
+ #
+ # You can change the name under which comments are registered:
+ # config.comments_registration_name = 'AdminComment'
+ #
+ # You can change the order for the comments and you can change the column
+ # to be used for ordering:
+ # config.comments_order = 'created_at ASC'
+ #
+ # You can disable the menu item for the comments index page:
+ # config.comments_menu = false
+ #
+ # You can customize the comment menu:
+ # config.comments_menu = { parent: 'Admin', priority: 1 }
+
+ # == Batch Actions
+ #
+ # Enable and disable Batch Actions
+ #
+ config.batch_actions = true
+
+ # == Controller Filters
+ #
+ # You can add before, after and around filters to all of your
+ # Active Admin resources and pages from here.
+ #
+ # config.before_action :do_something_awesome
+
+ # == Attribute Filters
+ #
+ # You can exclude possibly sensitive model attributes from being displayed,
+ # added to forms, or exported by default by ActiveAdmin
+ #
+ config.filter_attributes = [:encrypted_password, :password, :password_confirmation]
+
+ # == Localize Date/Time Format
+ #
+ # Set the localize format to display dates and times.
+ # To understand how to localize your app with I18n, read more at
+ # https://guides.rubyonrails.org/i18n.html
+ #
+ # You can run `bin/rails runner 'puts I18n.t("date.formats")'` to see the
+ # available formats in your application.
+ #
+ config.localize_format = :long
+
+ # == Setting a Favicon
+ #
+ # config.favicon = 'favicon.ico'
+
+ # == Meta Tags
+ #
+ # Add additional meta tags to the head element of active admin pages.
+ #
+ # Add tags to all pages logged in users see:
+ # config.meta_tags = { author: 'My Company' }
+
+ # By default, sign up/sign in/recover password pages are excluded
+ # from showing up in search engine results by adding a robots meta
+ # tag. You can reset the hash of meta tags included in logged out
+ # pages:
+ # config.meta_tags_for_logged_out_pages = {}
+
+ # == Removing Breadcrumbs
+ #
+ # Breadcrumbs are enabled by default. You can customize them for individual
+ # resources or you can disable them globally from here.
+ #
+ # config.breadcrumb = false
+
+ # == Create Another Checkbox
+ #
+ # Create another checkbox is disabled by default. You can customize it for individual
+ # resources or you can enable them globally from here.
+ #
+ # config.create_another = true
+
+ # == Register Stylesheets & Javascripts
+ #
+ # We recommend using the built in Active Admin layout and loading
+ # up your own stylesheets / javascripts to customize the look
+ # and feel.
+ #
+ # To load a stylesheet:
+ # config.register_stylesheet 'my_stylesheet.css'
+ #
+ # You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
+ # config.register_stylesheet 'my_print_stylesheet.css', media: :print
+ #
+ # To load a javascript file:
+ # config.register_javascript 'my_javascript.js'
+
+ # == CSV options
+ #
+ # Set the CSV builder separator
+ # config.csv_options = { col_sep: ';' }
+ #
+ # Force the use of quotes
+ # config.csv_options = { force_quotes: true }
+
+ # == Menu System
+ #
+ # You can add a navigation menu to be used in your application, or configure a provided menu
+ #
+ # To change the default utility navigation to show a link to your website & a logout btn
+ #
+ # config.namespace :admin do |admin|
+ # admin.build_menu :utility_navigation do |menu|
+ # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
+ # admin.add_logout_button_to_menu menu
+ # end
+ # end
+ #
+ # If you wanted to add a static menu item to the default menu provided:
+ #
+ # config.namespace :admin do |admin|
+ # admin.build_menu :default do |menu|
+ # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
+ # end
+ # end
+
+ # == Download Links
+ #
+ # You can disable download links on resource listing pages,
+ # or customize the formats shown per namespace/globally
+ #
+ # To disable/customize for the :admin namespace:
+ #
+ # config.namespace :admin do |admin|
+ #
+ # # Disable the links entirely
+ # admin.download_links = false
+ #
+ # # Only show XML & PDF options
+ # admin.download_links = [:xml, :pdf]
+ #
+ # # Enable/disable the links based on block
+ # # (for example, with cancan)
+ # admin.download_links = proc { can?(:view_download_links) }
+ #
+ # end
+
+ # == Pagination
+ #
+ # Pagination is enabled by default for all resources.
+ # You can control the default per page count for all resources here.
+ #
+ # config.default_per_page = 30
+ #
+ # You can control the max per page count too.
+ #
+ # config.max_per_page = 10_000
+
+ # == Filters
+ #
+ # By default the index screen includes a "Filters" sidebar on the right
+ # hand side with a filter for each attribute of the registered model.
+ # You can enable or disable them for all resources here.
+ #
+ # config.filters = true
+ #
+ # By default the filters include associations in a select, which means
+ # that every record will be loaded for each association (up
+ # to the value of config.maximum_association_filter_arity).
+ # You can enabled or disable the inclusion
+ # of those filters by default here.
+ #
+ # config.include_default_association_filters = true
+
+ # config.maximum_association_filter_arity = 256 # default value of :unlimited will change to 256 in a future version
+ # config.filter_columns_for_large_association, [
+ # :display_name,
+ # :full_name,
+ # :name,
+ # :username,
+ # :login,
+ # :title,
+ # :email,
+ # ]
+ # config.filter_method_for_large_association, '_starts_with'
+
+ # == Head
+ #
+ # You can add your own content to the site head like analytics. Make sure
+ # you only pass content you trust.
+ #
+ # config.head = ''.html_safe
+
+ # == Footer
+ #
+ # By default, the footer shows the current Active Admin version. You can
+ # override the content of the footer here.
+ #
+ # config.footer = 'my custom footer text'
+
+ # == Sorting
+ #
+ # By default ActiveAdmin::OrderClause is used for sorting logic
+ # You can inherit it with own class and inject it for all resources
+ #
+ # config.order_clause = MyOrderClause
+
+ # == Webpacker
+ #
+ # By default, Active Admin uses Sprocket's asset pipeline.
+ # You can switch to using Webpacker here.
+ #
+ # config.use_webpacker = true
+end
diff --git a/spec/dummy/config/initializers/application_controller_renderer.rb b/spec/dummy/config/initializers/application_controller_renderer.rb
new file mode 100644
index 0000000..89d2efa
--- /dev/null
+++ b/spec/dummy/config/initializers/application_controller_renderer.rb
@@ -0,0 +1,8 @@
+# Be sure to restart your server when you modify this file.
+
+# ActiveSupport::Reloader.to_prepare do
+# ApplicationController.renderer.defaults.merge!(
+# http_host: 'example.org',
+# https: false
+# )
+# end
diff --git a/spec/dummy/config/initializers/assets.rb b/spec/dummy/config/initializers/assets.rb
new file mode 100644
index 0000000..fe48fc3
--- /dev/null
+++ b/spec/dummy/config/initializers/assets.rb
@@ -0,0 +1,12 @@
+# 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.
+Rails.application.config.assets.version = '1.0'
+
+# Add additional assets to the asset load path.
+# Rails.application.config.assets.paths << Emoji.images_path
+
+# Precompile additional assets.
+# application.js, application.css, and all non-JS/CSS in the app/assets
+# folder are already added.
+# Rails.application.config.assets.precompile += %w( admin.js admin.css )
diff --git a/spec/dummy/config/initializers/backtrace_silencers.rb b/spec/dummy/config/initializers/backtrace_silencers.rb
new file mode 100644
index 0000000..59385cd
--- /dev/null
+++ b/spec/dummy/config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# 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.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
diff --git a/spec/dummy/config/initializers/content_security_policy.rb b/spec/dummy/config/initializers/content_security_policy.rb
new file mode 100644
index 0000000..41c4301
--- /dev/null
+++ b/spec/dummy/config/initializers/content_security_policy.rb
@@ -0,0 +1,28 @@
+# Be sure to restart your server when you modify this file.
+
+# Define an application-wide content security policy
+# For further information see the following documentation
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
+
+# Rails.application.config.content_security_policy do |policy|
+# policy.default_src :self, :https
+# policy.font_src :self, :https, :data
+# policy.img_src :self, :https, :data
+# policy.object_src :none
+# policy.script_src :self, :https
+# policy.style_src :self, :https
+
+# # Specify URI for violation reports
+# # policy.report_uri "/csp-violation-report-endpoint"
+# end
+
+# If you are using UJS then enable automatic nonce generation
+# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
+
+# Set the nonce only to specific directives
+# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
+
+# Report CSP violations to a specified URI
+# For further information see the following documentation:
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
+# Rails.application.config.content_security_policy_report_only = true
diff --git a/spec/dummy/config/initializers/cookies_serializer.rb b/spec/dummy/config/initializers/cookies_serializer.rb
new file mode 100644
index 0000000..5a6a32d
--- /dev/null
+++ b/spec/dummy/config/initializers/cookies_serializer.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
+# Specify a serializer for the signed and encrypted cookie jars.
+# Valid options are :json, :marshal, and :hybrid.
+Rails.application.config.action_dispatch.cookies_serializer = :json
diff --git a/spec/dummy/config/initializers/filter_parameter_logging.rb b/spec/dummy/config/initializers/filter_parameter_logging.rb
new file mode 100644
index 0000000..4a994e1
--- /dev/null
+++ b/spec/dummy/config/initializers/filter_parameter_logging.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Configure sensitive parameters which will be filtered from the log file.
+Rails.application.config.filter_parameters += [:password]
diff --git a/spec/dummy/config/initializers/inflections.rb b/spec/dummy/config/initializers/inflections.rb
new file mode 100644
index 0000000..ac033bf
--- /dev/null
+++ b/spec/dummy/config/initializers/inflections.rb
@@ -0,0 +1,16 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format. Inflections
+# are locale specific, and you may define rules for as many different
+# locales as you wish. All of these examples are active by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
+
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.acronym 'RESTful'
+# end
diff --git a/spec/dummy/config/initializers/mime_types.rb b/spec/dummy/config/initializers/mime_types.rb
new file mode 100644
index 0000000..dc18996
--- /dev/null
+++ b/spec/dummy/config/initializers/mime_types.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
diff --git a/spec/dummy/config/initializers/wrap_parameters.rb b/spec/dummy/config/initializers/wrap_parameters.rb
new file mode 100644
index 0000000..bbfc396
--- /dev/null
+++ b/spec/dummy/config/initializers/wrap_parameters.rb
@@ -0,0 +1,14 @@
+# Be sure to restart your server when you modify this file.
+
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
+
+# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
+ActiveSupport.on_load(:action_controller) do
+ wrap_parameters format: [:json]
+end
+
+# To enable root element in JSON for ActiveRecord objects.
+# ActiveSupport.on_load(:active_record) do
+# self.include_root_in_json = true
+# end
diff --git a/spec/dummy/config/locales/en.yml b/spec/dummy/config/locales/en.yml
new file mode 100644
index 0000000..cf9b342
--- /dev/null
+++ b/spec/dummy/config/locales/en.yml
@@ -0,0 +1,33 @@
+# Files in the config/locales directory are used for internationalization
+# and are automatically loaded by Rails. If you want to use locales other
+# than English, add the necessary files in this directory.
+#
+# To use the locales, use `I18n.t`:
+#
+# I18n.t 'hello'
+#
+# In views, this is aliased to just `t`:
+#
+# <%= t('hello') %>
+#
+# To use a different locale, set it with `I18n.locale`:
+#
+# I18n.locale = :es
+#
+# This would use the information in config/locales/es.yml.
+#
+# The following keys must be escaped otherwise they will not be retrieved by
+# the default I18n backend:
+#
+# true, false, on, off, yes, no
+#
+# Instead, surround them with single quotes.
+#
+# en:
+# 'true': 'foo'
+#
+# To learn more, please read the Rails Internationalization guide
+# available at https://guides.rubyonrails.org/i18n.html.
+
+en:
+ hello: "Hello world"
diff --git a/spec/dummy/config/puma.rb b/spec/dummy/config/puma.rb
new file mode 100644
index 0000000..5ed4437
--- /dev/null
+++ b/spec/dummy/config/puma.rb
@@ -0,0 +1,38 @@
+# Puma can serve each request in a thread from an internal thread pool.
+# The `threads` method setting takes two numbers: a minimum and maximum.
+# 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
+# and maximum; this matches the default thread size of Active Record.
+#
+max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
+min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
+threads min_threads_count, max_threads_count
+
+# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
+#
+port ENV.fetch("PORT") { 3000 }
+
+# Specifies the `environment` that Puma will run in.
+#
+environment ENV.fetch("RAILS_ENV") { "development" }
+
+# Specifies the `pidfile` that Puma will use.
+pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
+
+# Specifies the number of `workers` to boot in clustered mode.
+# Workers are forked web server processes. If using threads and workers together
+# the concurrency of the application would be max `threads` * `workers`.
+# Workers do not work on JRuby or Windows (both of which do not support
+# processes).
+#
+# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
+
+# Use the `preload_app!` method when specifying a `workers` number.
+# This directive tells Puma to first boot the application and load code
+# before forking the application. This takes advantage of Copy On Write
+# process behavior so workers use less memory.
+#
+# preload_app!
+
+# Allow puma to be restarted by `rails restart` command.
+plugin :tmp_restart
diff --git a/spec/dummy/config/routes.rb b/spec/dummy/config/routes.rb
new file mode 100644
index 0000000..36d2dac
--- /dev/null
+++ b/spec/dummy/config/routes.rb
@@ -0,0 +1,3 @@
+Rails.application.routes.draw do
+ ActiveAdmin.routes(self)
+end
diff --git a/spec/dummy/config/spring.rb b/spec/dummy/config/spring.rb
new file mode 100644
index 0000000..db5bf13
--- /dev/null
+++ b/spec/dummy/config/spring.rb
@@ -0,0 +1,6 @@
+Spring.watch(
+ ".ruby-version",
+ ".rbenv-vars",
+ "tmp/restart.txt",
+ "tmp/caching-dev.txt"
+)
diff --git a/spec/dummy/config/storage.yml b/spec/dummy/config/storage.yml
new file mode 100644
index 0000000..695f17b
--- /dev/null
+++ b/spec/dummy/config/storage.yml
@@ -0,0 +1,7 @@
+test:
+ service: Disk
+ root: <%= Rails.root.join("tmp/storage") %>
+
+local:
+ service: Disk
+ root: <%= Rails.root.join("storage") %>
diff --git a/spec/dummy/db/migrate/20170806125915_create_active_storage_tables.active_storage.rb b/spec/dummy/db/migrate/20170806125915_create_active_storage_tables.active_storage.rb
new file mode 100644
index 0000000..0b2ce25
--- /dev/null
+++ b/spec/dummy/db/migrate/20170806125915_create_active_storage_tables.active_storage.rb
@@ -0,0 +1,27 @@
+# This migration comes from active_storage (originally 20170806125915)
+class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
+ def change
+ create_table :active_storage_blobs do |t|
+ t.string :key, null: false
+ t.string :filename, null: false
+ t.string :content_type
+ t.text :metadata
+ t.bigint :byte_size, null: false
+ t.string :checksum, null: false
+ t.datetime :created_at, null: false
+
+ t.index [ :key ], unique: true
+ end
+
+ create_table :active_storage_attachments do |t|
+ t.string :name, null: false
+ t.references :record, null: false, polymorphic: true, index: false
+ t.references :blob, null: false
+
+ t.datetime :created_at, null: false
+
+ t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
+ t.foreign_key :active_storage_blobs, column: :blob_id
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20180101010101_create_active_admin_comments.rb b/spec/dummy/db/migrate/20180101010101_create_active_admin_comments.rb
new file mode 100644
index 0000000..0332a27
--- /dev/null
+++ b/spec/dummy/db/migrate/20180101010101_create_active_admin_comments.rb
@@ -0,0 +1,16 @@
+class CreateActiveAdminComments < ActiveRecord::Migration[6.0]
+ def self.up
+ create_table :active_admin_comments do |t|
+ t.string :namespace
+ t.text :body
+ t.references :resource, polymorphic: true
+ t.references :author, polymorphic: true
+ t.timestamps
+ end
+ add_index :active_admin_comments, [:namespace]
+ end
+
+ def self.down
+ drop_table :active_admin_comments
+ end
+end
diff --git a/spec/dummy/db/migrate/20180607053251_create_authors.rb b/spec/dummy/db/migrate/20180607053251_create_authors.rb
new file mode 100644
index 0000000..c9b8593
--- /dev/null
+++ b/spec/dummy/db/migrate/20180607053251_create_authors.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class CreateAuthors < ActiveRecord::Migration[5.2]
+ def change
+ create_table :authors do |t|
+ t.string :name
+ t.integer :age
+ t.string :email
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20180607053254_create_profiles.rb b/spec/dummy/db/migrate/20180607053254_create_profiles.rb
new file mode 100644
index 0000000..ddd2df0
--- /dev/null
+++ b/spec/dummy/db/migrate/20180607053254_create_profiles.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class CreateProfiles < ActiveRecord::Migration[5.2]
+ def change
+ create_table :profiles do |t|
+ t.text :description
+ t.belongs_to :author, foreign_key: true
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20180607053255_create_tags.rb b/spec/dummy/db/migrate/20180607053255_create_tags.rb
new file mode 100644
index 0000000..bade84e
--- /dev/null
+++ b/spec/dummy/db/migrate/20180607053255_create_tags.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class CreateTags < ActiveRecord::Migration[5.2]
+ def change
+ create_table :tags do |t|
+ t.string :name
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20180607053257_create_post_tags.rb b/spec/dummy/db/migrate/20180607053257_create_post_tags.rb
new file mode 100644
index 0000000..bbcfee6
--- /dev/null
+++ b/spec/dummy/db/migrate/20180607053257_create_post_tags.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class CreatePostTags < ActiveRecord::Migration[5.2]
+ def change
+ create_table :post_tags do |t|
+ t.belongs_to :post, foreign_key: true
+ t.belongs_to :tag, foreign_key: true
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20180607053739_create_posts.rb b/spec/dummy/db/migrate/20180607053739_create_posts.rb
new file mode 100644
index 0000000..305a66d
--- /dev/null
+++ b/spec/dummy/db/migrate/20180607053739_create_posts.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class CreatePosts < ActiveRecord::Migration[5.2]
+ def change
+ create_table :posts do |t|
+ t.string :title
+ t.text :description
+ t.belongs_to :author, foreign_key: true
+ t.string :category
+ t.datetime :dt
+ t.float :position
+ t.boolean :published
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb
new file mode 100644
index 0000000..15beb10
--- /dev/null
+++ b/spec/dummy/db/schema.rb
@@ -0,0 +1,99 @@
+# 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.
+#
+# This file is the source Rails uses to define your schema when running `rails
+# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema.define(version: 2018_06_07_053739) do
+
+ create_table "active_admin_comments", force: :cascade do |t|
+ t.string "namespace"
+ t.text "body"
+ t.string "resource_type"
+ t.integer "resource_id"
+ t.string "author_type"
+ t.integer "author_id"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id"
+ t.index ["namespace"], name: "index_active_admin_comments_on_namespace"
+ t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id"
+ end
+
+ create_table "active_storage_attachments", force: :cascade do |t|
+ t.string "name", null: false
+ t.string "record_type", null: false
+ t.integer "record_id", null: false
+ t.integer "blob_id", null: false
+ t.datetime "created_at", null: false
+ t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
+ t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
+ end
+
+ create_table "active_storage_blobs", force: :cascade do |t|
+ t.string "key", null: false
+ t.string "filename", null: false
+ t.string "content_type"
+ t.text "metadata"
+ t.bigint "byte_size", null: false
+ t.string "checksum", null: false
+ t.datetime "created_at", null: false
+ t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
+ end
+
+ create_table "authors", force: :cascade do |t|
+ t.string "name"
+ t.integer "age"
+ t.string "email"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ create_table "post_tags", force: :cascade do |t|
+ t.integer "post_id"
+ t.integer "tag_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["post_id"], name: "index_post_tags_on_post_id"
+ t.index ["tag_id"], name: "index_post_tags_on_tag_id"
+ end
+
+ create_table "posts", force: :cascade do |t|
+ t.string "title"
+ t.text "description"
+ t.integer "author_id"
+ t.string "category"
+ t.datetime "dt"
+ t.float "position"
+ t.boolean "published"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["author_id"], name: "index_posts_on_author_id"
+ end
+
+ create_table "profiles", force: :cascade do |t|
+ t.text "description"
+ t.integer "author_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["author_id"], name: "index_profiles_on_author_id"
+ end
+
+ create_table "tags", force: :cascade do |t|
+ t.string "name"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
+ add_foreign_key "post_tags", "posts"
+ add_foreign_key "post_tags", "tags"
+ add_foreign_key "posts", "authors"
+ add_foreign_key "profiles", "authors"
+end
diff --git a/spec/dummy/lib/assets/.keep b/spec/dummy/lib/assets/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/dummy/public/404.html b/spec/dummy/public/404.html
new file mode 100644
index 0000000..2be3af2
--- /dev/null
+++ b/spec/dummy/public/404.html
@@ -0,0 +1,67 @@
+
+
+
+ The page you were looking for doesn't exist (404)
+
+
+
+
+
+
+
+
+
The page you were looking for doesn't exist.
+
You may have mistyped the address or the page may have moved.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/spec/dummy/public/422.html b/spec/dummy/public/422.html
new file mode 100644
index 0000000..c08eac0
--- /dev/null
+++ b/spec/dummy/public/422.html
@@ -0,0 +1,67 @@
+
+
+
+ The change you wanted was rejected (422)
+
+
+
+
+
+
+
+
+
The change you wanted was rejected.
+
Maybe you tried to change something you didn't have access to.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/spec/dummy/public/500.html b/spec/dummy/public/500.html
new file mode 100644
index 0000000..78a030a
--- /dev/null
+++ b/spec/dummy/public/500.html
@@ -0,0 +1,66 @@
+
+
+
+ We're sorry, but something went wrong (500)
+
+
+
+
+
+
+
+
+
We're sorry, but something went wrong.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/spec/dummy/public/apple-touch-icon-precomposed.png b/spec/dummy/public/apple-touch-icon-precomposed.png
new file mode 100644
index 0000000..e69de29
diff --git a/spec/dummy/public/apple-touch-icon.png b/spec/dummy/public/apple-touch-icon.png
new file mode 100644
index 0000000..e69de29
diff --git a/spec/dummy/public/favicon.ico b/spec/dummy/public/favicon.ico
new file mode 100644
index 0000000..e69de29
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
new file mode 100644
index 0000000..0493988
--- /dev/null
+++ b/spec/rails_helper.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+ENV['RAILS_ENV'] = 'test'
+
+require File.expand_path('dummy/config/environment.rb', __dir__)
+
+abort('The Rails environment is running in production mode!') if Rails.env.production?
+
+require 'rspec/rails'
+require 'capybara/rails'
+
+Dir[File.expand_path('support/**/*.rb', __dir__)].sort.each { |f| require f }
+
+require 'simplecov'
+SimpleCov.start :rails do
+ filters.clear
+ add_filter %r{^/spec/}
+end
+
+# Force deprecations to raise an exception.
+ActiveSupport::Deprecation.behavior = :raise
+
+# Checks for pending migrations and applies them before tests are run.
+# If you are not using ActiveRecord, you can remove these lines.
+begin
+ ActiveRecord::Migration.maintain_test_schema!
+rescue ActiveRecord::PendingMigrationError => e
+ puts e.to_s.strip
+ exit 1
+end
+
+RSpec.configure do |config|
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+ config.infer_spec_type_from_file_location!
+ config.filter_rails_from_backtrace!
+
+ config.use_transactional_fixtures = true
+ config.use_instantiated_fixtures = false
+ config.render_views = false
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..a7be4b5
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ config.disable_monkey_patching!
+ config.filter_run focus: true
+ config.filter_run_excluding changes_filesystem: true
+ config.run_all_when_everything_filtered = true
+ config.color = true
+ config.order = :random
+ config.example_status_persistence_file_path = '.rspec_failures'
+
+ config.shared_context_metadata_behavior = :apply_to_host_groups
+
+ config.expect_with :rspec do |expectations|
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+ end
+ config.mock_with :rspec do |mocks|
+ mocks.verify_partial_doubles = true
+ end
+end
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
new file mode 100644
index 0000000..47fbd05
--- /dev/null
+++ b/spec/support/capybara.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+Capybara.server = :puma
diff --git a/spec/support/drivers.rb b/spec/support/drivers.rb
new file mode 100644
index 0000000..5211d39
--- /dev/null
+++ b/spec/support/drivers.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ config.before(:each, type: :system) do
+ driven_by(:selenium_chrome_headless)
+ end
+end