diff --git a/.rubocop.yml b/.rubocop.yml index afac4b6..758c46e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -33,3 +33,7 @@ Style/ExplicitBlockArgument: Style/GuardClause: Exclude: - lib/tiny_admin/router.rb + +Style/StringLiterals: + Enabled: true + EnforcedStyle: double_quotes diff --git a/Gemfile b/Gemfile index 10b926d..797b015 100644 --- a/Gemfile +++ b/Gemfile @@ -1,34 +1,34 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } gemspec group :development, :test do - gem 'rails', '~> 7.1' + gem "rails", "~> 7.1" - gem 'sqlite3', '< 2.0' - gem 'tilt' - gem 'warden' - gem 'webrick' + gem "sqlite3", "< 2.0" + gem "tilt" + gem "warden" + gem "webrick" - gem 'rbs' + gem "rbs" # Testing - gem 'capybara' - gem 'capybara-screenshot' - gem 'rspec-rails' - gem 'simplecov', require: false + gem "capybara" + gem "capybara-screenshot" + gem "rspec-rails" + gem "simplecov", require: false # Linters # gem 'fasterer' - gem 'rubocop' - gem 'rubocop-packaging' - gem 'rubocop-performance' - gem 'rubocop-rspec' + gem "rubocop" + gem "rubocop-packaging" + gem "rubocop-performance" + gem "rubocop-rspec" # Tools # gem 'overcommit', '~> 0.59' - gem 'pry-rails' + gem "pry-rails" end diff --git a/lib/tiny_admin.rb b/lib/tiny_admin.rb index 9809665..0446655 100644 --- a/lib/tiny_admin.rb +++ b/lib/tiny_admin.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require 'phlex' -require 'roda' -require 'zeitwerk' +require "phlex" +require "roda" +require "zeitwerk" -require 'forwardable' -require 'singleton' -require 'yaml' +require "forwardable" +require "singleton" +require "yaml" loader = Zeitwerk::Loader.for_gem loader.setup @@ -25,10 +25,10 @@ def configure_from_file(file) end def route_for(section, reference: nil, action: nil, query: nil) - root_path = settings.root_path == '/' ? nil : settings.root_path + root_path = settings.root_path == "/" ? nil : settings.root_path route = [root_path, section, reference, action].compact.join("/") route << "?#{query}" if query - route[0] == '/' ? route : route.prepend('/') + route[0] == "/" ? route : route.prepend("/") end def settings diff --git a/lib/tiny_admin/actions/index.rb b/lib/tiny_admin/actions/index.rb index fd62a77..0c15349 100644 --- a/lib/tiny_admin/actions/index.rb +++ b/lib/tiny_admin/actions/index.rb @@ -45,14 +45,14 @@ def evaluate_options(options) @params = context.request.params @repository = context.repository @pagination = options[:pagination] || 10 - @current_page = (params['p'] || 1).to_i - @query_string = params_to_s(params.except('p')) + @current_page = (params["p"] || 1).to_i + @query_string = params_to_s(params.except("p")) end def prepare_filters(fields) filters = (options[:filters] || []).map { _1.is_a?(Hash) ? _1 : { field: _1 } } filters = filters.to_h { |filter| [filter[:field], filter] } - values = params['q'] || {} + values = params["q"] || {} fields.each_with_object({}) do |(name, field), result| result[field] = { value: values[name], filter: filters[name] } if filters.key?(name) end diff --git a/lib/tiny_admin/authentication.rb b/lib/tiny_admin/authentication.rb index 1111c45..88cfb84 100644 --- a/lib/tiny_admin/authentication.rb +++ b/lib/tiny_admin/authentication.rb @@ -3,7 +3,7 @@ module TinyAdmin class Authentication < BasicApp route do |r| - r.get 'unauthenticated' do + r.get "unauthenticated" do if current_user r.redirect TinyAdmin.settings.root_path else @@ -11,15 +11,15 @@ class Authentication < BasicApp end end - r.post 'unauthenticated' do + r.post "unauthenticated" do warning = TinyAdmin.settings.helper_class.label_for( - 'Failed to authenticate', - options: ['authentication.unauthenticated'] + "Failed to authenticate", + options: ["authentication.unauthenticated"] ) render_login(warnings: [warning]) end - r.get 'logout' do + r.get "logout" do logout_user r.redirect TinyAdmin.settings.root_path end @@ -33,9 +33,9 @@ def render_login(notices: nil, warnings: nil, errors: nil) page = prepare_page(login, options: %i[no_menu compact_layout]) page.messages = { - notices: notices || flash['notices'], - warnings: warnings || flash['warnings'], - errors: errors || flash['errors'] + notices: notices || flash["notices"], + warnings: warnings || flash["warnings"], + errors: errors || flash["errors"] } render(inline: page.call) end diff --git a/lib/tiny_admin/basic_app.rb b/lib/tiny_admin/basic_app.rb index 234bd66..1d73ce4 100644 --- a/lib/tiny_admin/basic_app.rb +++ b/lib/tiny_admin/basic_app.rb @@ -14,7 +14,7 @@ def authentication_plugin plugin :flash plugin :not_found - plugin :render, engine: 'html' + plugin :render, engine: "html" plugin :sessions, secret: SecureRandom.hex(64) plugin authentication_plugin, TinyAdmin.settings.authentication diff --git a/lib/tiny_admin/field.rb b/lib/tiny_admin/field.rb index 7be4946..85748eb 100644 --- a/lib/tiny_admin/field.rb +++ b/lib/tiny_admin/field.rb @@ -12,13 +12,13 @@ def initialize(name:, title:, type:, options: {}) end def apply_call_option(target) - messages = (options[:call] || '').split(',').map(&:strip) + messages = (options[:call] || "").split(",").map(&:strip) messages.inject(target) { |result, msg| result&.send(msg) } if messages.any? end def translate_value(value) if options && options[:method] - method, *args = options[:method].split(',').map(&:strip) + method, *args = options[:method].split(",").map(&:strip) if options[:converter] Object.const_get(options[:converter]).send(method, value, options: args || []) else @@ -32,7 +32,7 @@ def translate_value(value) class << self def create_field(name:, title: nil, type: nil, options: {}) field_name = name.to_s - field_title = field_name.respond_to?(:humanize) ? field_name.humanize : field_name.tr('_', ' ').capitalize + field_title = field_name.respond_to?(:humanize) ? field_name.humanize : field_name.tr("_", " ").capitalize new(name: field_name, title: title || field_title, type: type || :string, options: options || {}) end end diff --git a/lib/tiny_admin/plugins/active_record_repository.rb b/lib/tiny_admin/plugins/active_record_repository.rb index 52c2ecd..75b1c0b 100644 --- a/lib/tiny_admin/plugins/active_record_repository.rb +++ b/lib/tiny_admin/plugins/active_record_repository.rb @@ -54,7 +54,7 @@ def list(page: 1, limit: 10, sort: nil, filters: nil) def apply_filters(query, filters) filters.each do |field, filter| value = filter&.dig(:value) - next if value.nil? || value == '' + next if value.nil? || value == "" query = case field.type diff --git a/lib/tiny_admin/plugins/no_auth.rb b/lib/tiny_admin/plugins/no_auth.rb index e840a97..11d1a3e 100644 --- a/lib/tiny_admin/plugins/no_auth.rb +++ b/lib/tiny_admin/plugins/no_auth.rb @@ -13,7 +13,7 @@ def authenticate_user! # rubocop:disable Naming/PredicateMethod end def current_user - 'admin' + "admin" end def logout_user diff --git a/lib/tiny_admin/plugins/simple_auth.rb b/lib/tiny_admin/plugins/simple_auth.rb index b8cdf4f..25969b3 100644 --- a/lib/tiny_admin/plugins/simple_auth.rb +++ b/lib/tiny_admin/plugins/simple_auth.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'digest' +require "digest" module TinyAdmin module Plugins @@ -8,14 +8,14 @@ module SimpleAuth class << self def configure(app, opts = {}) @@opts = opts || {} # rubocop:disable Style/ClassVars - @@opts[:password] ||= ENV.fetch('ADMIN_PASSWORD_HASH', nil) # NOTE: fallback value + @@opts[:password] ||= ENV.fetch("ADMIN_PASSWORD_HASH", nil) # NOTE: fallback value Warden::Strategies.add(:secret) do def authenticate! - secret = params['secret'] || '' + secret = params["secret"] || "" return fail(:invalid_credentials) if Digest::SHA512.hexdigest(secret) != @@opts[:password] - success!(app: 'TinyAdmin') + success!(app: "TinyAdmin") end end @@ -29,15 +29,15 @@ def authenticate! module InstanceMethods def authenticate_user! - env['warden'].authenticate! + env["warden"].authenticate! end def current_user - env['warden'].user + env["warden"].user end def logout_user - env['warden'].logout + env["warden"].logout end end end diff --git a/lib/tiny_admin/router.rb b/lib/tiny_admin/router.rb index d7b5061..2a372b0 100644 --- a/lib/tiny_admin/router.rb +++ b/lib/tiny_admin/router.rb @@ -9,7 +9,7 @@ class Router < BasicApp route do |r| TinyAdmin.settings.load_settings - r.on 'auth' do + r.on "auth" do r.run Authentication end @@ -25,7 +25,7 @@ class Router < BasicApp # :nocov: end - r.post '' do + r.post "" do r.redirect TinyAdmin.settings.root_path end @@ -48,7 +48,7 @@ def store def render_page(page) if page.respond_to?(:messages=) - page.messages = { notices: flash['notices'], warnings: flash['warnings'], errors: flash['errors'] } + page.messages = { notices: flash["notices"], warnings: flash["warnings"], errors: flash["errors"] } end render(inline: page.call) end @@ -99,7 +99,7 @@ def setup_collection_routes(req, slug, options:) ) # Index - if options[:only].include?(:index) || options[:only].include?('index') + if options[:only].include?(:index) || options[:only].include?("index") req.is do if authorization.allowed?(current_user, :resource_index, slug) context = Context.new( @@ -134,7 +134,7 @@ def setup_member_routes(req, slug, options:) ) # Show - if options[:only].include?(:show) || options[:only].include?('show') + if options[:only].include?(:show) || options[:only].include?("show") req.is do if authorization.allowed?(current_user, :resource_show, slug) context = Context.new( diff --git a/lib/tiny_admin/settings.rb b/lib/tiny_admin/settings.rb index 882fe9c..1f546a0 100644 --- a/lib/tiny_admin/settings.rb +++ b/lib/tiny_admin/settings.rb @@ -19,9 +19,9 @@ class Settings %i[page_not_found] => Views::Pages::PageNotFound, %i[record_not_found] => Views::Pages::RecordNotFound, %i[repository] => Plugins::ActiveRecordRepository, - %i[root_path] => '/admin', + %i[root_path] => "/admin", %i[root page] => Views::Pages::Root, - %i[root title] => 'TinyAdmin', + %i[root title] => "TinyAdmin", %i[sections] => [] }.freeze @@ -78,11 +78,11 @@ def load_settings end @store ||= TinyAdmin::Store.new(self) - self.root_path = '/' if root_path == '' + self.root_path = "/" if root_path == "" if authentication[:plugin] <= Plugins::SimpleAuth logout_path = "#{root_path}/auth/logout" - authentication[:logout] ||= TinyAdmin::Section.new(name: 'logout', slug: 'logout', path: logout_path) + authentication[:logout] ||= TinyAdmin::Section.new(name: "logout", slug: "logout", path: logout_path) end store.prepare_sections(sections, logout: authentication[:logout]) end diff --git a/lib/tiny_admin/store.rb b/lib/tiny_admin/store.rb index e02f341..9c0f7ed 100644 --- a/lib/tiny_admin/store.rb +++ b/lib/tiny_admin/store.rb @@ -56,7 +56,7 @@ def add_resource_section(slug, section) repository: to_class(section[:repository] || settings.repository) ) - hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?('hidden')) + hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?("hidden")) TinyAdmin::Section.new(name: section[:name], slug: slug) unless hidden end diff --git a/lib/tiny_admin/support.rb b/lib/tiny_admin/support.rb index a5be97a..2ce1025 100644 --- a/lib/tiny_admin/support.rb +++ b/lib/tiny_admin/support.rb @@ -24,7 +24,7 @@ def round(value, options: []) end def strftime(value, options: []) - value&.strftime(options&.first || '%Y-%m-%d %H:%M') + value&.strftime(options&.first || "%Y-%m-%d %H:%M") end def to_date(value, options: []) diff --git a/lib/tiny_admin/utils.rb b/lib/tiny_admin/utils.rb index e653e08..ee4527b 100644 --- a/lib/tiny_admin/utils.rb +++ b/lib/tiny_admin/utils.rb @@ -11,7 +11,7 @@ def params_to_s(params) result.push(["#{param}=#{value}"]) end end - list.join('&') + list.join("&") end def prepare_page(page_class, slug: nil, attributes: nil, options: nil, params: nil) @@ -40,9 +40,9 @@ def to_class(klass) end def humanize(string) - return '' unless string + return "" unless string - string.respond_to?(:humanize) ? string.humanize : string.tr('_', ' ').capitalize + string.respond_to?(:humanize) ? string.humanize : string.tr("_", " ").capitalize end end end diff --git a/lib/tiny_admin/version.rb b/lib/tiny_admin/version.rb index 8f53400..c429adb 100644 --- a/lib/tiny_admin/version.rb +++ b/lib/tiny_admin/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TinyAdmin - VERSION = '0.10.1' + VERSION = "0.10.1" end diff --git a/lib/tiny_admin/views/actions/index.rb b/lib/tiny_admin/views/actions/index.rb index a092d02..a57d048 100644 --- a/lib/tiny_admin/views/actions/index.rb +++ b/lib/tiny_admin/views/actions/index.rb @@ -15,22 +15,22 @@ class Index < DefaultLayout def view_template super do - div(class: 'index') { - div(class: 'row') { - div(class: 'col-4') { - h1(class: 'title') { + div(class: "index") { + div(class: "row") { + div(class: "col-4") { + h1(class: "title") { title } } - div(class: 'col-8') { + div(class: "col-8") { actions_buttons } } - div(class: 'row') { - div_class = filters&.any? ? 'col-9' : 'col-12' + div(class: "row") { + div_class = filters&.any? ? "col-9" : "col-12" div(class: div_class) { - table(class: 'table') { + table(class: "table") { table_header if fields.any? table_body @@ -40,7 +40,7 @@ def view_template } if filters&.any? - div(class: 'col-3') { + div(class: "col-3") { filters_form = TinyAdmin::Views::Components::FiltersForm.new filters_form.update_attributes(section_path: TinyAdmin.route_for(slug), filters: filters) render filters_form @@ -80,15 +80,15 @@ def table_body } end - td(class: 'actions p-1') { - div(class: 'btn-group btn-group-sm') { - link_class = 'btn btn-outline-secondary' + td(class: "actions p-1") { + div(class: "btn-group btn-group-sm") { + link_class = "btn btn-outline-secondary" if links links.each do |link| whitespace - if link == 'show' + if link == "show" a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) { - label_for('Show', options: ['actions.index.links.show']) + label_for("Show", options: ["actions.index.links.show"]) } else a(href: TinyAdmin.route_for(slug, reference: record.id, action: link), class: link_class) { @@ -99,7 +99,7 @@ def table_body end else a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) { - label_for('Show', options: ['actions.index.links.show']) + label_for("Show", options: ["actions.index.links.show"]) } end } @@ -110,11 +110,11 @@ def table_body end def actions_buttons - ul(class: 'nav justify-content-end') { + ul(class: "nav justify-content-end") { (actions || {}).each do |action, action_class| - li(class: 'nav-item mx-1') { + li(class: "nav-item mx-1") { href = TinyAdmin.route_for(slug, action: action) - a(href: href, class: 'nav-link btn btn-outline-secondary') { + a(href: href, class: "nav-link btn btn-outline-secondary") { action_class.respond_to?(:title) ? action_class.title : action } } diff --git a/lib/tiny_admin/views/actions/show.rb b/lib/tiny_admin/views/actions/show.rb index 8f85b17..499ebe0 100644 --- a/lib/tiny_admin/views/actions/show.rb +++ b/lib/tiny_admin/views/actions/show.rb @@ -13,12 +13,12 @@ class Show < DefaultLayout def view_template super do - div(class: 'show') { - div(class: 'row') { - div(class: 'col-4') { - h1(class: 'title') { title } + div(class: "show") { + div(class: "row") { + div(class: "col-4") { + h1(class: "title") { title } } - div(class: 'col-8') { + div(class: "col-8") { actions_buttons } } @@ -27,9 +27,9 @@ def view_template field = fields[key] div(class: "field-#{field.name} row lh-lg") { if field - div(class: 'field-header col-2') { field.options[:header] || field.title } + div(class: "field-header col-2") { field.options[:header] || field.title } end - div(class: 'field-value col-10') { + div(class: "field-value col-10") { render TinyAdmin.settings.components[:field_value].new(field, value, record: record) } } @@ -43,11 +43,11 @@ def view_template private def actions_buttons - ul(class: 'nav justify-content-end') { + ul(class: "nav justify-content-end") { (actions || {}).each do |action, action_class| - li(class: 'nav-item mx-1') { + li(class: "nav-item mx-1") { href = TinyAdmin.route_for(slug, reference: reference, action: action) - a(href: href, class: 'nav-link btn btn-outline-secondary') { + a(href: href, class: "nav-link btn btn-outline-secondary") { action_class.respond_to?(:title) ? action_class.title : action } } diff --git a/lib/tiny_admin/views/components/field_value.rb b/lib/tiny_admin/views/components/field_value.rb index 3703f94..8d0695e 100644 --- a/lib/tiny_admin/views/components/field_value.rb +++ b/lib/tiny_admin/views/components/field_value.rb @@ -14,7 +14,7 @@ def initialize(field, value, record:) def view_template translated_value = field.translate_value(value) - value_class = field.options[:options]&.include?('value_class') ? "value-#{value}" : nil + value_class = field.options[:options]&.include?("value_class") ? "value-#{value}" : nil if field.options[:link_to] a(href: TinyAdmin.route_for(field.options[:link_to], reference: translated_value)) { span(class: value_class) { diff --git a/lib/tiny_admin/views/components/filters_form.rb b/lib/tiny_admin/views/components/filters_form.rb index d22ee02..f917275 100644 --- a/lib/tiny_admin/views/components/filters_form.rb +++ b/lib/tiny_admin/views/components/filters_form.rb @@ -7,49 +7,49 @@ class FiltersForm < BasicComponent attr_accessor :filters, :section_path def view_template - form(class: 'form_filters', method: 'get') { + form(class: "form_filters", method: "get") { filters.each do |field, filter| name = field.name filter_data = filter[:filter] - div(class: 'mb-3') { - label(for: "filter-#{name}", class: 'form-label') { field.title } + div(class: "mb-3") { + label(for: "filter-#{name}", class: "form-label") { field.title } case filter_data[:type]&.to_sym || field.type when :boolean - select(class: 'form-select', id: "filter-#{name}", name: "q[#{name}]") { - option(value: '') { '-' } - option(value: '0', selected: filter[:value] == '0') { - TinyAdmin.settings.helper_class.label_for('false', options: ['components.filters_form.boolean.false']) + select(class: "form-select", id: "filter-#{name}", name: "q[#{name}]") { + option(value: "") { "-" } + option(value: "0", selected: filter[:value] == "0") { + TinyAdmin.settings.helper_class.label_for("false", options: ["components.filters_form.boolean.false"]) } - option(value: '1', selected: filter[:value] == '1') { - TinyAdmin.settings.helper_class.label_for('true', options: ['components.filters_form.boolean.true']) + option(value: "1", selected: filter[:value] == "1") { + TinyAdmin.settings.helper_class.label_for("true", options: ["components.filters_form.boolean.true"]) } } when :date - input(type: 'date', class: 'form-control', id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) + input(type: "date", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) when :datetime - input(type: 'datetime-local', class: 'form-control', id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) + input(type: "datetime-local", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) when :integer - input(type: 'number', class: 'form-control', id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) + input(type: "number", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) when :select - select(class: 'form-select', id: "filter-#{name}", name: "q[#{name}]") { - option(value: '') { '-' } + select(class: "form-select", id: "filter-#{name}", name: "q[#{name}]") { + option(value: "") { "-" } filter_data[:values].each do |value| option(selected: filter[:value] == value) { value } end } else - input(type: 'text', class: 'form-control', id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) + input(type: "text", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value]) end } end - div(class: 'mt-3') { - a(href: section_path, class: 'button_clear btn btn-secondary text-white') { - TinyAdmin.settings.helper_class.label_for('Clear', options: ['components.filters_form.buttons.clear']) + div(class: "mt-3") { + a(href: section_path, class: "button_clear btn btn-secondary text-white") { + TinyAdmin.settings.helper_class.label_for("Clear", options: ["components.filters_form.buttons.clear"]) } whitespace - button(type: 'submit', class: 'button_filter btn btn-secondary') { - TinyAdmin.settings.helper_class.label_for('Filter', options: ['components.filters_form.buttons.submit']) + button(type: "submit", class: "button_filter btn btn-secondary") { + TinyAdmin.settings.helper_class.label_for("Filter", options: ["components.filters_form.buttons.submit"]) } } } diff --git a/lib/tiny_admin/views/components/flash.rb b/lib/tiny_admin/views/components/flash.rb index 308cbe6..65d736e 100644 --- a/lib/tiny_admin/views/components/flash.rb +++ b/lib/tiny_admin/views/components/flash.rb @@ -12,10 +12,10 @@ def view_template warnings = messages[:warnings] errors = messages[:errors] - div(class: 'flash') { - div(class: 'notices alert alert-success', role: 'alert') { notices.join(', ') } if notices&.any? - div(class: 'notices alert alert-warning', role: 'alert') { warnings.join(', ') } if warnings&.any? - div(class: 'notices alert alert-danger', role: 'alert') { errors.join(', ') } if errors&.any? + div(class: "flash") { + div(class: "notices alert alert-success", role: "alert") { notices.join(", ") } if notices&.any? + div(class: "notices alert alert-warning", role: "alert") { warnings.join(", ") } if warnings&.any? + div(class: "notices alert alert-danger", role: "alert") { errors.join(", ") } if errors&.any? } end end diff --git a/lib/tiny_admin/views/components/head.rb b/lib/tiny_admin/views/components/head.rb index c80922a..f0d017b 100644 --- a/lib/tiny_admin/views/components/head.rb +++ b/lib/tiny_admin/views/components/head.rb @@ -8,8 +8,8 @@ class Head < BasicComponent def view_template head { - meta charset: 'utf-8' - meta name: 'viewport', content: 'width=device-width, initial-scale=1' + meta charset: "utf-8" + meta name: "viewport", content: "width=device-width, initial-scale=1" title { page_title } diff --git a/lib/tiny_admin/views/components/navbar.rb b/lib/tiny_admin/views/components/navbar.rb index d9a6bf5..40810fe 100644 --- a/lib/tiny_admin/views/components/navbar.rb +++ b/lib/tiny_admin/views/components/navbar.rb @@ -7,29 +7,29 @@ class Navbar < BasicComponent attr_accessor :current_slug, :items, :root_path, :root_title def view_template - nav(class: 'navbar navbar-expand-lg') { - div(class: 'container') { - a(class: 'navbar-brand', href: root_path) { root_title } + nav(class: "navbar navbar-expand-lg") { + div(class: "container") { + a(class: "navbar-brand", href: root_path) { root_title } button( - class: 'navbar-toggler', - type: 'button', - 'data-bs-toggle' => 'collapse', - 'data-bs-target' => '#navbarNav', - 'aria-controls' => 'navbarNav', - 'aria-expanded' => 'false', - 'aria-label' => 'Toggle navigation' + class: "navbar-toggler", + type: "button", + "data-bs-toggle" => "collapse", + "data-bs-target" => "#navbarNav", + "aria-controls" => "navbarNav", + "aria-expanded" => "false", + "aria-label" => "Toggle navigation" ) { - span(class: 'navbar-toggler-icon') + span(class: "navbar-toggler-icon") } - div(class: 'collapse navbar-collapse', id: 'navbarNav') { - ul(class: 'navbar-nav') { + div(class: "collapse navbar-collapse", id: "navbarNav") { + ul(class: "navbar-nav") { items.each do |item| classes = %w[nav-link] - classes << 'active' if item.slug == current_slug - link_attributes = { class: classes.join(' '), href: item.path, 'aria-current' => 'page' } + classes << "active" if item.slug == current_slug + link_attributes = { class: classes.join(" "), href: item.path, "aria-current" => "page" } link_attributes.merge!(item.options) if item.options - li(class: 'nav-item') { + li(class: "nav-item") { a(**link_attributes) { item.name } } end diff --git a/lib/tiny_admin/views/components/pagination.rb b/lib/tiny_admin/views/components/pagination.rb index d40ed0d..c6d71e0 100644 --- a/lib/tiny_admin/views/components/pagination.rb +++ b/lib/tiny_admin/views/components/pagination.rb @@ -7,14 +7,14 @@ class Pagination < BasicComponent attr_accessor :current, :pages, :query_string, :total_count def view_template - div(class: 'container') { - div(class: 'row') { - div(class: 'col total-count') { + div(class: "container") { + div(class: "row") { + div(class: "col total-count") { "#{total_count} items" } - div(class: 'col col-6 text-center pagination-div') { - nav(class: 'd-inline-block', 'aria-label': 'Pagination') { - ul(class: 'pagination') { + div(class: "col col-6 text-center pagination-div") { + nav(class: "d-inline-block", "aria-label": "Pagination") { + ul(class: "pagination") { if pages <= 10 pages_range(1..pages) elsif current <= 4 || current >= pages - 3 @@ -28,7 +28,7 @@ def view_template } } } - div(class: 'col') + div(class: "col") } } end @@ -37,17 +37,17 @@ def view_template def pages_range(range, with_dots: false) range.each do |page| - li(class: page == current ? 'page-item active' : 'page-item') { + li(class: page == current ? "page-item active" : "page-item") { href = query_string.empty? ? "?p=#{page}" : "?#{query_string}&p=#{page}" - a(class: 'page-link', href: href) { page } + a(class: "page-link", href: href) { page } } end dots if with_dots end def dots - li(class: 'page-item disabled') { - a(class: 'page-link') { '...' } + li(class: "page-item disabled") { + a(class: "page-link") { "..." } } end end diff --git a/lib/tiny_admin/views/components/widgets.rb b/lib/tiny_admin/views/components/widgets.rb index b4a3476..ef13e07 100644 --- a/lib/tiny_admin/views/components/widgets.rb +++ b/lib/tiny_admin/views/components/widgets.rb @@ -11,15 +11,15 @@ def initialize(widgets) def view_template return if @widgets.nil? || @widgets.empty? - div(class: 'container widgets') { + div(class: "container widgets") { @widgets.each_slice(2).each do |row| - div(class: 'row') { + div(class: "row") { row.each do |widget| next unless widget < Phlex::HTML - div(class: 'col') { - div(class: 'card') { - div(class: 'card-body') { + div(class: "col") { + div(class: "card") { + div(class: "card-body") { render widget.new } } diff --git a/lib/tiny_admin/views/default_layout.rb b/lib/tiny_admin/views/default_layout.rb index 1c79a84..ca7270e 100644 --- a/lib/tiny_admin/views/default_layout.rb +++ b/lib/tiny_admin/views/default_layout.rb @@ -35,10 +35,10 @@ def body_class end def main_content - div(class: 'container main-content py-4') do + div(class: "container main-content py-4") do if options&.include?(:compact_layout) - div(class: 'row justify-content-center') { - div(class: 'col-6') { + div(class: "row justify-content-center") { + div(class: "col-6") { yield } } @@ -52,10 +52,10 @@ def style_links TinyAdmin.settings.style_links || [ # Bootstrap CDN { - href: 'https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css', - rel: 'stylesheet', - integrity: 'sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65', - crossorigin: 'anonymous' + href: "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css", + rel: "stylesheet", + integrity: "sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65", + crossorigin: "anonymous" } ] end diff --git a/lib/tiny_admin/views/pages/content.rb b/lib/tiny_admin/views/pages/content.rb index 7cc40bb..b860722 100644 --- a/lib/tiny_admin/views/pages/content.rb +++ b/lib/tiny_admin/views/pages/content.rb @@ -6,8 +6,8 @@ module Pages class Content < DefaultLayout def view_template super do - div(class: 'content') { - div(class: 'content-data') { + div(class: "content") { + div(class: "content-data") { unsafe_raw(content) } diff --git a/lib/tiny_admin/views/pages/page_not_allowed.rb b/lib/tiny_admin/views/pages/page_not_allowed.rb index 77d423d..574dc6a 100644 --- a/lib/tiny_admin/views/pages/page_not_allowed.rb +++ b/lib/tiny_admin/views/pages/page_not_allowed.rb @@ -6,14 +6,14 @@ module Pages class PageNotAllowed < DefaultLayout def view_template super do - div(class: 'page_not_allowed') { - h1(class: 'title') { title } + div(class: "page_not_allowed") { + h1(class: "title") { title } } end end def title - 'Page not allowed' + "Page not allowed" end end end diff --git a/lib/tiny_admin/views/pages/page_not_found.rb b/lib/tiny_admin/views/pages/page_not_found.rb index a3da537..0403d50 100644 --- a/lib/tiny_admin/views/pages/page_not_found.rb +++ b/lib/tiny_admin/views/pages/page_not_found.rb @@ -6,14 +6,14 @@ module Pages class PageNotFound < DefaultLayout def view_template super do - div(class: 'page_not_found') { - h1(class: 'title') { title } + div(class: "page_not_found") { + h1(class: "title") { title } } end end def title - 'Page not found' + "Page not found" end end end diff --git a/lib/tiny_admin/views/pages/record_not_found.rb b/lib/tiny_admin/views/pages/record_not_found.rb index 1d04ccb..db1b873 100644 --- a/lib/tiny_admin/views/pages/record_not_found.rb +++ b/lib/tiny_admin/views/pages/record_not_found.rb @@ -6,14 +6,14 @@ module Pages class RecordNotFound < DefaultLayout def view_template super do - div(class: 'record_not_found') { - h1(class: 'title') { title } + div(class: "record_not_found") { + h1(class: "title") { title } } end end def title - 'Record not found' + "Record not found" end end end diff --git a/lib/tiny_admin/views/pages/root.rb b/lib/tiny_admin/views/pages/root.rb index 9e44fd9..0235e9a 100644 --- a/lib/tiny_admin/views/pages/root.rb +++ b/lib/tiny_admin/views/pages/root.rb @@ -6,7 +6,7 @@ module Pages class Root < DefaultLayout def view_template super do - div(class: 'root') { + div(class: "root") { render TinyAdmin::Views::Components::Widgets.new(widgets) } end diff --git a/lib/tiny_admin/views/pages/simple_auth_login.rb b/lib/tiny_admin/views/pages/simple_auth_login.rb index 6af433c..50f943f 100644 --- a/lib/tiny_admin/views/pages/simple_auth_login.rb +++ b/lib/tiny_admin/views/pages/simple_auth_login.rb @@ -6,20 +6,20 @@ module Pages class SimpleAuthLogin < DefaultLayout def view_template super do - div(class: 'simple_auth_login') { - h1(class: 'title') { title } + div(class: "simple_auth_login") { + h1(class: "title") { title } - form(class: 'form_login', method: 'post') { - div(class: 'mt-3') { - label(for: 'secret', class: 'form-label') { - label_for('Password', options: ['pages.simple_auth_login.inputs.password']) + form(class: "form_login", method: "post") { + div(class: "mt-3") { + label(for: "secret", class: "form-label") { + label_for("Password", options: ["pages.simple_auth_login.inputs.password"]) } - input(type: 'password', name: 'secret', class: 'form-control', id: 'secret') + input(type: "password", name: "secret", class: "form-control", id: "secret") } - div(class: 'mt-3') { - button(type: 'submit', class: 'button_login btn btn-primary') { - label_for('Login', options: ['pages.simple_auth_login.buttons.submit']) + div(class: "mt-3") { + button(type: "submit", class: "button_login btn btn-primary") { + label_for("Login", options: ["pages.simple_auth_login.buttons.submit"]) } } } @@ -28,7 +28,7 @@ def view_template end def title - 'Login' + "Login" end end end diff --git a/spec/dummy_rails_app.rb b/spec/dummy_rails_app.rb index ccdf83e..3c1d034 100644 --- a/spec/dummy_rails_app.rb +++ b/spec/dummy_rails_app.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true -ENV['RAILS_ENV'] ||= 'test' -require File.expand_path('dummy_rails/config/environment', __dir__) +ENV["RAILS_ENV"] ||= "test" +require File.expand_path("dummy_rails/config/environment", __dir__) diff --git a/spec/features/components/navbar_spec.rb b/spec/features/components/navbar_spec.rb index 6134a4e..ddf8152 100644 --- a/spec/features/components/navbar_spec.rb +++ b/spec/features/components/navbar_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Navbar component', type: :feature do +RSpec.describe "Navbar component", type: :feature do before do - visit '/admin' + visit "/admin" log_in end - it 'shows the navbar buttons', :aggregate_failures do - expect(page).to have_link('Test Admin', href: '/admin', class: 'navbar-brand') - expect(page).to have_link('Google.it', href: 'https://www.google.it', class: 'nav-link') - expect(page).to have_link('Sample page', href: '/admin/sample', class: 'nav-link') - expect(page).to have_link('Authors', href: '/admin/authors', class: 'nav-link') - expect(page).to have_link('Posts', href: '/admin/posts', class: 'nav-link') + it "shows the navbar buttons", :aggregate_failures do + expect(page).to have_link("Test Admin", href: "/admin", class: "navbar-brand") + expect(page).to have_link("Google.it", href: "https://www.google.it", class: "nav-link") + expect(page).to have_link("Sample page", href: "/admin/sample", class: "nav-link") + expect(page).to have_link("Authors", href: "/admin/authors", class: "nav-link") + expect(page).to have_link("Posts", href: "/admin/posts", class: "nav-link") end end diff --git a/spec/features/components/pagination_spec.rb b/spec/features/components/pagination_spec.rb index aa0c9e5..d7fd90b 100644 --- a/spec/features/components/pagination_spec.rb +++ b/spec/features/components/pagination_spec.rb @@ -1,52 +1,52 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Pagination component', type: :feature do +RSpec.describe "Pagination component", type: :feature do def page_links - find_all('a.page-link').map(&:text) + find_all("a.page-link").map(&:text) end - context 'with a collection with less than 10 pages' do + context "with a collection with less than 10 pages" do before do setup_data(posts_count: 15) - visit '/admin' + visit "/admin" log_in - click_link('Posts') + click_link("Posts") end - it 'shows the pagination widget', :aggregate_failures do - expect(page).to have_css('ul', class: 'pagination') - expect(page).to have_link('1', class: 'page-link', href: '?p=1') - expect(page_links).to eq(['1', '2', '3']) + it "shows the pagination widget", :aggregate_failures do + expect(page).to have_css("ul", class: "pagination") + expect(page).to have_link("1", class: "page-link", href: "?p=1") + expect(page_links).to eq(["1", "2", "3"]) end end - context 'with a collection with more than 10 pages' do + context "with a collection with more than 10 pages" do before do setup_data(posts_count: 60) - visit '/admin' + visit "/admin" log_in end - it 'shows the pagination widget', :aggregate_failures do - click_link('Posts') + it "shows the pagination widget", :aggregate_failures do + click_link("Posts") - expect(page).to have_css('ul', class: 'pagination') - expect(page).to have_link('1', class: 'page-link', href: '?p=12') - expect(page_links).to eq(['1', '2', '3', '...', '10', '11', '12']) + expect(page).to have_css("ul", class: "pagination") + expect(page).to have_link("1", class: "page-link", href: "?p=12") + expect(page_links).to eq(["1", "2", "3", "...", "10", "11", "12"]) end - context 'when opening a specific page' do + context "when opening a specific page" do before do - visit '/admin/posts?p=6' + visit "/admin/posts?p=6" end - it 'shows the pagination widget', :aggregate_failures do - expect(page).to have_css('ul', class: 'pagination') - expect(page).to have_link('6', class: 'page-link', href: '?p=6') - expect(page_links).to eq(['1', '...', '4', '5', '6', '7', '8', '...', '12']) + it "shows the pagination widget", :aggregate_failures do + expect(page).to have_css("ul", class: "pagination") + expect(page).to have_link("6", class: "page-link", href: "?p=6") + expect(page_links).to eq(["1", "...", "4", "5", "6", "7", "8", "...", "12"]) end end end diff --git a/spec/features/pages/content_spec.rb b/spec/features/pages/content_spec.rb index 458b183..9f599d7 100644 --- a/spec/features/pages/content_spec.rb +++ b/spec/features/pages/content_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Content', type: :feature do +RSpec.describe "Content", type: :feature do before do - visit '/admin' + visit "/admin" log_in end - it 'loads a test content page', :aggregate_failures do - click_link('Test content') - expect(page).to have_current_path('/admin/test-content') - expect(page).to have_css('p', text: 'Some test content') + it "loads a test content page", :aggregate_failures do + click_link("Test content") + expect(page).to have_current_path("/admin/test-content") + expect(page).to have_css("p", text: "Some test content") end end diff --git a/spec/features/pages/page_not_found_spec.rb b/spec/features/pages/page_not_found_spec.rb index 726ba1f..01ef858 100644 --- a/spec/features/pages/page_not_found_spec.rb +++ b/spec/features/pages/page_not_found_spec.rb @@ -1,16 +1,16 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Page not found', type: :feature do +RSpec.describe "Page not found", type: :feature do before do - visit '/admin/aaa' + visit "/admin/aaa" log_in end - it 'loads the page not found', :aggregate_failures do - expect(page).to have_current_path('/admin/aaa') - expect(page).to have_content('Page not found') + it "loads the page not found", :aggregate_failures do + expect(page).to have_current_path("/admin/aaa") + expect(page).to have_content("Page not found") end end diff --git a/spec/features/pages/pages_spec.rb b/spec/features/pages/pages_spec.rb index 7750a8f..9f4d4cd 100644 --- a/spec/features/pages/pages_spec.rb +++ b/spec/features/pages/pages_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Pages', type: :feature do +RSpec.describe "Pages", type: :feature do before do - visit '/admin' + visit "/admin" log_in end - it 'loads a sample page', :aggregate_failures do - click_link('Sample page') - expect(page).to have_current_path('/admin/sample') - expect(page).to have_css('p', text: 'This is just a sample page') + it "loads a sample page", :aggregate_failures do + click_link("Sample page") + expect(page).to have_current_path("/admin/sample") + expect(page).to have_css("p", text: "This is just a sample page") end end diff --git a/spec/features/pages/root_spec.rb b/spec/features/pages/root_spec.rb index eb567c0..67b2dfd 100644 --- a/spec/features/pages/root_spec.rb +++ b/spec/features/pages/root_spec.rb @@ -1,31 +1,31 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Root', type: :feature do - context 'when opening the root url' do +RSpec.describe "Root", type: :feature do + context "when opening the root url" do before do - visit '/admin' + visit "/admin" log_in end - it 'loads the root page', :aggregate_failures do - expect(page).to have_current_path('/admin') - expect(page).to have_css('.root') + it "loads the root page", :aggregate_failures do + expect(page).to have_current_path("/admin") + expect(page).to have_css(".root") end end - context 'when redirect option is set' do + context "when redirect option is set" do before do - allow(TinyAdmin.settings).to receive(:root).and_return(redirect: 'posts') - visit '/admin' + allow(TinyAdmin.settings).to receive(:root).and_return(redirect: "posts") + visit "/admin" log_in end - it 'loads the root page', :aggregate_failures do - expect(page).to have_current_path('/admin/posts') - expect(page).to have_css('h1.title', text: 'Posts') + it "loads the root page", :aggregate_failures do + expect(page).to have_current_path("/admin/posts") + expect(page).to have_css("h1.title", text: "Posts") end end end diff --git a/spec/features/plugins/authenticator_spec.rb b/spec/features/plugins/authenticator_spec.rb index 08f01ad..737f382 100644 --- a/spec/features/plugins/authenticator_spec.rb +++ b/spec/features/plugins/authenticator_spec.rb @@ -1,53 +1,53 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Authenticator plugin', type: :feature do +RSpec.describe "Authenticator plugin", type: :feature do before do - visit '/admin' + visit "/admin" end - it 'shows the login form', :aggregate_failures do - expect(page).to have_current_path('/admin') - expect(page).to have_content('Login') - expect(page).to have_css('form.form_login .button_login') + it "shows the login form", :aggregate_failures do + expect(page).to have_current_path("/admin") + expect(page).to have_content("Login") + expect(page).to have_css("form.form_login .button_login") end - context 'when the authentication fails' do - it 'shows the authentication error', :aggregate_failures do - expect(page).not_to have_content('Failed to authenticate') - log_in(password: 'wrong password') - expect(page).to have_content('Failed to authenticate') - expect(page).to have_current_path('/admin') + context "when the authentication fails" do + it "shows the authentication error", :aggregate_failures do + expect(page).not_to have_content("Failed to authenticate") + log_in(password: "wrong password") + expect(page).to have_content("Failed to authenticate") + expect(page).to have_current_path("/admin") end end - context 'when the authentication succeed' do - it 'proceeds with the login', :aggregate_failures do - expect(page).to have_css('form.form_login') + context "when the authentication succeed" do + it "proceeds with the login", :aggregate_failures do + expect(page).to have_css("form.form_login") log_in - expect(page).not_to have_content('Failed to authenticate') - expect(page).not_to have_css('form.form_login') + expect(page).not_to have_content("Failed to authenticate") + expect(page).not_to have_css("form.form_login") end end - context 'when the user is logged in' do + context "when the user is logged in" do before { log_in } - it 'proceeds with the logout', :aggregate_failures do - expect(page).not_to have_css('form.form_login') - click_link('logout') - expect(page).to have_css('form.form_login') - expect(page).to have_content('Login') + it "proceeds with the logout", :aggregate_failures do + expect(page).not_to have_css("form.form_login") + click_link("logout") + expect(page).to have_css("form.form_login") + expect(page).to have_content("Login") end - context 'when the user reopen the login page' do - it 'redirects to the root page', :aggregate_failures do - expect(page).not_to have_css('form.form_login') - visit '/admin/auth/unauthenticated' - expect(page).to have_current_path('/admin') - expect(page).not_to have_css('form.form_login') + context "when the user reopen the login page" do + it "redirects to the root page", :aggregate_failures do + expect(page).not_to have_css("form.form_login") + visit "/admin/auth/unauthenticated" + expect(page).to have_current_path("/admin") + expect(page).not_to have_css("form.form_login") end end end diff --git a/spec/features/plugins/authorization_spec.rb b/spec/features/plugins/authorization_spec.rb index 374d398..fd7b5b9 100644 --- a/spec/features/plugins/authorization_spec.rb +++ b/spec/features/plugins/authorization_spec.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Authorization plugin', type: :feature do +RSpec.describe "Authorization plugin", type: :feature do let(:root_content) { "Latest authors\nLatest posts" } around do |example| @@ -14,11 +14,11 @@ end before do - visit '/admin' + visit "/admin" log_in end - context 'with an Authorization class that restrict the root page' do + context "with an Authorization class that restrict the root page" do let(:some_class) do Class.new(TinyAdmin::Plugins::Authorization) do class << self @@ -31,19 +31,19 @@ def allowed?(_user, action, _param = nil) end end - it 'disallows the access to the root page when opened', :aggregate_failures do - expect(page).to have_content 'Page not allowed' - expect { click_on 'Sample page' } - .to change { page.find('.main-content').text }.to("Sample page\nThis is just a sample page") + it "disallows the access to the root page when opened", :aggregate_failures do + expect(page).to have_content "Page not allowed" + expect { click_on "Sample page" } + .to change { page.find(".main-content").text }.to("Sample page\nThis is just a sample page") end end - context 'with an Authorization class that restrict a specific page' do + context "with an Authorization class that restrict a specific page" do let(:some_class) do Class.new(TinyAdmin::Plugins::Authorization) do class << self def allowed?(_user, action, param = nil) - return false if action == :page && param == 'sample' + return false if action == :page && param == "sample" true end @@ -51,13 +51,13 @@ def allowed?(_user, action, param = nil) end end - it 'disallows the access to the page when opened' do - expect { click_on 'Sample page' } - .to change { page.find('.main-content').text }.from(root_content).to('Page not allowed') + it "disallows the access to the page when opened" do + expect { click_on "Sample page" } + .to change { page.find(".main-content").text }.from(root_content).to("Page not allowed") end end - context 'with an Authorization class that restrict resource index' do + context "with an Authorization class that restrict resource index" do let(:some_class) do Class.new(TinyAdmin::Plugins::Authorization) do class << self @@ -70,13 +70,13 @@ def allowed?(_user, action, _param = nil) end end - it 'disallows the access to the page when opened' do - expect { click_on 'Posts' } - .to change { page.find('.main-content').text }.from(root_content).to('Page not allowed') + it "disallows the access to the page when opened" do + expect { click_on "Posts" } + .to change { page.find(".main-content").text }.from(root_content).to("Page not allowed") end end - context 'with an Authorization class that restrict resource show' do + context "with an Authorization class that restrict resource show" do let(:some_class) do Class.new(TinyAdmin::Plugins::Authorization) do class << self @@ -91,19 +91,19 @@ def allowed?(_user, action, _param = nil) before { setup_data(posts_count: 1) } - it 'disallows the access to the page when opened' do - click_on 'Posts' - expect { click_on 'Show' } - .to change { page.find('.main-content').text }.to('Page not allowed') + it "disallows the access to the page when opened" do + click_on "Posts" + expect { click_on "Show" } + .to change { page.find(".main-content").text }.to("Page not allowed") end end - context 'with an Authorization class that restrict a specific custom action' do + context "with an Authorization class that restrict a specific custom action" do let(:some_class) do Class.new(TinyAdmin::Plugins::Authorization) do class << self def allowed?(_user, action, param = nil) - return false if action == :custom_action && param == 'sample_col' + return false if action == :custom_action && param == "sample_col" true end @@ -111,10 +111,10 @@ def allowed?(_user, action, param = nil) end end - it 'disallows the access to the page when opened' do - click_on 'Authors' - expect { click_on 'sample_col' } - .to change { page.find('.main-content').text }.to('Page not allowed') + it "disallows the access to the page when opened" do + click_on "Authors" + expect { click_on "sample_col" } + .to change { page.find(".main-content").text }.to("Page not allowed") end end end diff --git a/spec/features/resources_spec.rb b/spec/features/resources_spec.rb index 8314011..bd1a047 100644 --- a/spec/features/resources_spec.rb +++ b/spec/features/resources_spec.rb @@ -1,26 +1,26 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" -RSpec.describe 'Resources', type: :feature do +RSpec.describe "Resources", type: :feature do before { setup_data } - context 'when clicking on Authors menu item' do + context "when clicking on Authors menu item" do before do - visit '/admin' + visit "/admin" log_in - click_link('Authors') + click_link("Authors") end - it 'loads the index page', :aggregate_failures do + it "loads the index page", :aggregate_failures do author = Author.last - expect(page).to have_current_path('/admin/authors') - expect(page).to have_css('h1.title', text: 'Authors') - expect(page).to have_css('td', text: author.name) - expect(page).to have_css('td', text: author.email) - expect(page).to have_link('Show', href: "/admin/authors/#{author.id}") + expect(page).to have_current_path("/admin/authors") + expect(page).to have_css("h1.title", text: "Authors") + expect(page).to have_css("td", text: author.name) + expect(page).to have_css("td", text: author.email) + expect(page).to have_link("Show", href: "/admin/authors/#{author.id}") end end @@ -28,32 +28,32 @@ let(:author) { Author.first } before do - visit '/admin' + visit "/admin" log_in - click_link('Authors') - find('tr.row_1 a', text: 'Show').click + click_link("Authors") + find("tr.row_1 a", text: "Show").click end - it 'loads the show page', :aggregate_failures do - expect(page).to have_css('h1.title', text: "Author ##{author.id}") - expect(page).to have_css('div', text: author.email) - expect(page).to have_css('div', text: author.name) + it "loads the show page", :aggregate_failures do + expect(page).to have_css("h1.title", text: "Author ##{author.id}") + expect(page).to have_css("div", text: author.email) + expect(page).to have_css("div", text: author.name) end end context "when filtering by title in the post's listing page" do before do setup_data(posts_count: 15) - visit '/admin/posts?some_var=1' + visit "/admin/posts?some_var=1" log_in end - it 'shows the filtered index page', :aggregate_failures do - expect(page).not_to have_css('td', text: Post.last.title) - fill_in('q[title]', with: Post.last.title) - fill_in('q[author_id]', with: Post.last.author_id) - page.find('form.form_filters .button_filter').click - expect(page).to have_css('td', text: Post.last.title) + it "shows the filtered index page", :aggregate_failures do + expect(page).not_to have_css("td", text: Post.last.title) + fill_in("q[title]", with: Post.last.title) + fill_in("q[author_id]", with: Post.last.author_id) + page.find("form.form_filters .button_filter").click + expect(page).to have_css("td", text: Post.last.title) end end @@ -61,55 +61,55 @@ let(:post) { Post.first } before do - visit '/admin' + visit "/admin" log_in - click_link('Posts') - find('tr.row_1 a', text: 'Show').click + click_link("Posts") + find("tr.row_1 a", text: "Show").click end - it 'loads the show page', :aggregate_failures do - expect(page).to have_css('h1.title', text: "Post ##{post.id}") - expect(page).to have_css('div', text: post.title) + it "loads the show page", :aggregate_failures do + expect(page).to have_css("h1.title", text: "Post ##{post.id}") + expect(page).to have_css("div", text: post.title) end end - context 'when the url of a missing author is loaded' do + context "when the url of a missing author is loaded" do before do - visit '/admin/authors/0123456789' + visit "/admin/authors/0123456789" log_in end - it 'loads the record not found page', :aggregate_failures do - expect(page).to have_current_path('/admin/authors/0123456789') - expect(page).to have_css('h1.title', text: 'Record not found') + it "loads the record not found page", :aggregate_failures do + expect(page).to have_current_path("/admin/authors/0123456789") + expect(page).to have_css("h1.title", text: "Record not found") end end - context 'when opening a custom collection action url' do + context "when opening a custom collection action url" do before do - visit '/admin' + visit "/admin" log_in - visit '/admin/authors/sample_col' + visit "/admin/authors/sample_col" end - it 'loads the custom action page', :aggregate_failures do - expect(page).to have_current_path('/admin/authors/sample_col') - expect(page).to have_content('Custom collection action') + it "loads the custom action page", :aggregate_failures do + expect(page).to have_current_path("/admin/authors/sample_col") + expect(page).to have_content("Custom collection action") end end - context 'when opening a custom member action url' do + context "when opening a custom member action url" do let(:author) { Author.first } before do - visit '/admin' + visit "/admin" log_in visit "/admin/authors/#{author.id}/sample_mem" end - it 'loads the custom action page', :aggregate_failures do + it "loads the custom action page", :aggregate_failures do expect(page).to have_current_path("/admin/authors/#{author.id}/sample_mem") - expect(page).to have_content('Custom member action') + expect(page).to have_content("Custom member action") end end end diff --git a/spec/lib/tiny_admin/plugins/no_auth_spec.rb b/spec/lib/tiny_admin/plugins/no_auth_spec.rb index 2f777aa..0a82578 100644 --- a/spec/lib/tiny_admin/plugins/no_auth_spec.rb +++ b/spec/lib/tiny_admin/plugins/no_auth_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'dummy_rails_app' -require 'rails_helper' +require "dummy_rails_app" +require "rails_helper" RSpec.describe TinyAdmin::Plugins::NoAuth do let(:some_class) do @@ -10,21 +10,21 @@ end end - before { stub_const('SomeClass', some_class) } + before { stub_const("SomeClass", some_class) } - describe '#authenticate_user!' do + describe "#authenticate_user!" do subject(:authenticate_user!) { SomeClass.new.authenticate_user! } it { is_expected.to be_truthy } end - describe '#current_user' do + describe "#current_user" do subject(:current_user) { SomeClass.new.current_user } - it { is_expected.to eq 'admin' } + it { is_expected.to eq "admin" } end - describe '#logout_user' do + describe "#logout_user" do subject(:logout_user) { SomeClass.new.logout_user } it { is_expected.to be_nil } diff --git a/spec/lib/tiny_admin_spec.rb b/spec/lib/tiny_admin_spec.rb index 2a9347c..4e7394a 100644 --- a/spec/lib/tiny_admin_spec.rb +++ b/spec/lib/tiny_admin_spec.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -RSpec.describe 'TinyAdmin' do - describe '#configure_from_file' do +RSpec.describe "TinyAdmin" do + describe "#configure_from_file" do subject(:configure_from_file) { TinyAdmin.configure_from_file(file) } - let(:file) { file_fixture('basic_config.yml') } - let(:root) { { title: 'Test' } } + let(:file) { file_fixture("basic_config.yml") } + let(:root) { { title: "Test" } } let(:settings) { instance_double(TinyAdmin::Settings, :[]= => nil, reset!: nil) } before do @@ -13,8 +13,8 @@ configure_from_file end - it 'changes the settings' do - expect(settings).to have_received(:[]=).with(:root, title: 'Test Admin!') + it "changes the settings" do + expect(settings).to have_received(:[]=).with(:root, title: "Test Admin!") end end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 2dcee3b..f55ec4e 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -3,11 +3,11 @@ # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? -require 'rspec/rails' -require 'capybara/rails' -require 'capybara-screenshot/rspec' +require "rspec/rails" +require "capybara/rails" +require "capybara-screenshot/rspec" -Dir[File.expand_path('support/**/*.rb', __dir__)].each { |f| require f } +Dir[File.expand_path("support/**/*.rb", __dir__)].each { |f| require f } if defined? ActiveRecord # Checks for pending migrations and applies them before tests are run. @@ -27,6 +27,6 @@ config.filter_rails_from_backtrace! config.disable_monkey_patching! - config.include_context 'with some data' - config.include_context 'Capybara helpers' + config.include_context "with some data" + config.include_context "Capybara helpers" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c5155f7..68cd170 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require 'pry' -require 'simplecov' +require "pry" +require "simplecov" SimpleCov.start do enable_coverage :branch - add_filter '/spec/' + add_filter "/spec/" end RSpec.configure do |config| diff --git a/spec/support/capybara_helpers.rb b/spec/support/capybara_helpers.rb index 322cb0b..d5e79f6 100644 --- a/spec/support/capybara_helpers.rb +++ b/spec/support/capybara_helpers.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -RSpec.shared_context 'Capybara helpers' do # rubocop:disable RSpec/ContextWording - def log_in(password: 'changeme') - page.fill_in 'secret', with: password - page.find('form.form_login .button_login').click +RSpec.shared_context "Capybara helpers" do # rubocop:disable RSpec/ContextWording + def log_in(password: "changeme") + page.fill_in "secret", with: password + page.find("form.form_login .button_login").click end end diff --git a/spec/support/setup_data.rb b/spec/support/setup_data.rb index 6d6dcb0..a352df9 100644 --- a/spec/support/setup_data.rb +++ b/spec/support/setup_data.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_context 'with some data' do +RSpec.shared_context "with some data" do def setup_data(posts_count: 5) # Authors authors = Array.new(3) do @@ -11,7 +11,7 @@ def setup_data(posts_count: 5) # Posts posts_count.times do |i| post_ref = Post.count + 1 - Post.create!(author: authors[i % 3], title: "A post #{post_ref + i}", description: 'Some post content') + Post.create!(author: authors[i % 3], title: "A post #{post_ref + i}", description: "Some post content") end end end diff --git a/tiny_admin.gemspec b/tiny_admin.gemspec index 296de00..8bad8bd 100644 --- a/tiny_admin.gemspec +++ b/tiny_admin.gemspec @@ -1,35 +1,35 @@ # frozen_string_literal: true -$:.push File.expand_path('lib', __dir__) +$:.push File.expand_path("lib", __dir__) -require 'tiny_admin/version' +require "tiny_admin/version" Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY - spec.name = 'tiny_admin' + spec.name = "tiny_admin" spec.version = TinyAdmin::VERSION - spec.summary = 'Tiny Admin' - spec.description = 'A compact and composable dashboard component for Ruby' - spec.license = 'MIT' + spec.summary = "Tiny Admin" + spec.description = "A compact and composable dashboard component for Ruby" + spec.license = "MIT" - spec.required_ruby_version = '>= 3.0.0' + spec.required_ruby_version = ">= 3.0.0" - spec.author = 'Mattia Roccoberton' - spec.email = 'mat@blocknot.es' - spec.homepage = 'https://github.com/blocknotes/tiny_admin' + spec.author = "Mattia Roccoberton" + spec.email = "mat@blocknot.es" + spec.homepage = "https://github.com/blocknotes/tiny_admin" spec.metadata = { - 'homepage_uri' => spec.homepage, - 'source_code_uri' => spec.homepage, - 'changelog_uri' => 'https://github.com/blocknotes/tiny_admin/blob/main/CHANGELOG.md', - 'rubygems_mfa_required' => 'true' + "homepage_uri" => spec.homepage, + "source_code_uri" => spec.homepage, + "changelog_uri" => "https://github.com/blocknotes/tiny_admin/blob/main/CHANGELOG.md", + "rubygems_mfa_required" => "true" } - spec.files = Dir['{app,db,lib}/**/*', 'LICENSE.txt', 'README.md'] - spec.require_paths = ['lib'] + spec.files = Dir["{app,db,lib}/**/*", "LICENSE.txt", "README.md"] + spec.require_paths = ["lib"] - spec.add_dependency 'phlex', '~> 1', '>= 1.10.0' - spec.add_dependency 'roda', '~> 3' - spec.add_dependency 'tilt', '~> 2' - spec.add_dependency 'zeitwerk', '~> 2' + spec.add_dependency "phlex", "~> 1", ">= 1.10.0" + spec.add_dependency "roda", "~> 3" + spec.add_dependency "tilt", "~> 2" + spec.add_dependency "zeitwerk", "~> 2" end