godmin 1.3.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +0 -2
  3. data/.gitignore +1 -0
  4. data/.travis.yml +7 -15
  5. data/Appraisals +4 -4
  6. data/CHANGELOG.md +83 -2
  7. data/Gemfile +1 -2
  8. data/README.md +74 -9
  9. data/Rakefile +2 -10
  10. data/app/views/godmin/resource/_breadcrumb.html.erb +12 -24
  11. data/app/views/godmin/resource/_breadcrumb_actions.html.erb +41 -0
  12. data/app/views/godmin/resource/_button_actions.html.erb +1 -1
  13. data/app/views/godmin/resource/_table.html.erb +3 -0
  14. data/app/views/godmin/resource/columns/_actions.html.erb +4 -4
  15. data/app/views/godmin/resource/show.html.erb +1 -1
  16. data/config/locales/en.yml +2 -0
  17. data/config/locales/pt-BR.yml +2 -0
  18. data/config/locales/sv.yml +2 -0
  19. data/gemfiles/rails_5.gemfile +3 -4
  20. data/gemfiles/rails_6.gemfile +8 -0
  21. data/godmin.gemspec +18 -16
  22. data/lib/generators/godmin/resource/resource_generator.rb +7 -1
  23. data/lib/generators/godmin/resource/templates/resource_model.rb +4 -0
  24. data/lib/godmin/application_controller.rb +10 -11
  25. data/lib/godmin/authentication.rb +11 -11
  26. data/lib/godmin/authentication/sessions_controller.rb +2 -1
  27. data/lib/godmin/authorization.rb +6 -20
  28. data/lib/godmin/engine_wrapper.rb +10 -1
  29. data/lib/godmin/generators/base.rb +4 -4
  30. data/lib/godmin/generators/named_base.rb +4 -4
  31. data/lib/godmin/helpers/application.rb +3 -3
  32. data/lib/godmin/helpers/batch_actions.rb +1 -1
  33. data/lib/godmin/helpers/forms.rb +5 -1
  34. data/lib/godmin/paginator.rb +12 -4
  35. data/lib/godmin/resolver.rb +23 -5
  36. data/lib/godmin/resources/resource_controller.rb +24 -5
  37. data/lib/godmin/resources/resource_controller/batch_actions.rb +1 -1
  38. data/lib/godmin/resources/resource_service.rb +8 -7
  39. data/lib/godmin/resources/resource_service/associations.rb +23 -0
  40. data/lib/godmin/version.rb +1 -1
  41. data/template.rb +42 -7
  42. data/test/dummy/admin/app/controllers/admin/authorized_articles_controller.rb +15 -0
  43. data/test/dummy/admin/app/models/admin/article.rb +4 -0
  44. data/test/dummy/admin/app/policies/admin/article_policy.rb +7 -0
  45. data/test/dummy/admin/config/routes.rb +1 -0
  46. data/test/dummy/app/assets/config/manifest.js +4 -0
  47. data/test/dummy/app/controllers/another_admin_sessions_controller.rb +8 -0
  48. data/test/dummy/app/controllers/comments_controller.rb +3 -0
  49. data/test/dummy/app/models/another_admin_user.rb +7 -0
  50. data/test/dummy/app/models/article.rb +1 -0
  51. data/test/dummy/app/models/comment.rb +7 -0
  52. data/test/dummy/app/services/article_service.rb +2 -0
  53. data/test/dummy/app/services/comment_service.rb +7 -0
  54. data/test/dummy/bin/rails +1 -1
  55. data/test/dummy/config/application.rb +2 -14
  56. data/test/dummy/config/locales/en.yml +9 -0
  57. data/test/dummy/config/routes.rb +6 -1
  58. data/test/dummy/db/migrate/20150717121532_create_articles.rb +1 -1
  59. data/test/dummy/db/migrate/20150907133753_create_admin_users.rb +1 -1
  60. data/test/dummy/db/migrate/20160713134238_create_comment.rb +9 -0
  61. data/test/dummy/db/migrate/20170207081043_create_another_admin_user.rb +10 -0
  62. data/test/dummy/db/schema.rb +26 -11
  63. data/test/fakes/article.rb +1 -1
  64. data/test/fakes/article_service.rb +3 -7
  65. data/test/generators/resource_generator_test.rb +77 -0
  66. data/test/integration/authentication_test.rb +8 -0
  67. data/test/integration/authorization_test.rb +5 -0
  68. data/test/integration/nested_resources_test.rb +47 -0
  69. data/test/test_helper.rb +1 -4
  70. data/test/{lib/godmin → unit}/engine_wrapper_test.rb +1 -1
  71. data/test/{lib/godmin → unit}/helpers/filters_test.rb +0 -0
  72. data/test/{lib/godmin → unit}/paginator_test.rb +11 -0
  73. data/test/{lib/godmin → unit}/resolver_test.rb +0 -0
  74. data/test/{lib/godmin → unit}/resources/resource_service/batch_actions_test.rb +1 -1
  75. data/test/{lib/godmin → unit}/resources/resource_service/filters_test.rb +1 -1
  76. data/test/{lib/godmin → unit}/resources/resource_service/ordering_test.rb +1 -1
  77. data/test/{lib/godmin → unit}/resources/resource_service/pagination_test.rb +0 -0
  78. data/test/{lib/godmin → unit}/resources/resource_service/scopes_test.rb +0 -0
  79. data/test/{lib/godmin → unit}/resources/resource_service_test.rb +0 -0
  80. metadata +167 -107
  81. data/gemfiles/rails_4.gemfile +0 -9
  82. data/lib/godmin/authorization/policy_finder.rb +0 -31
  83. data/lib/tasks/godmin_tasks.rake +0 -4
  84. data/test/lib/godmin/policy_finder_test.rb +0 -55
@@ -0,0 +1,15 @@
1
+ require_dependency "admin/articles_controller"
2
+
3
+ module Admin
4
+ class AuthorizedArticlesController < ArticlesController
5
+ include Godmin::Authorization
6
+
7
+ def admin_user
8
+ "admin"
9
+ end
10
+
11
+ def resource_service_class
12
+ Admin::ArticleService
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module Admin
2
+ class Article < ::Article
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module Admin
2
+ class ArticlePolicy < Godmin::Authorization::Policy
3
+ def index?
4
+ false
5
+ end
6
+ end
7
+ end
@@ -1,4 +1,5 @@
1
1
  Admin::Engine.routes.draw do
2
2
  resources :articles
3
+ resources :authorized_articles
3
4
  root to: "application#welcome"
4
5
  end
@@ -0,0 +1,4 @@
1
+ //= link application.css
2
+ //= link application.js
3
+ //= link admin/application.css
4
+ //= link admin/application.js
@@ -0,0 +1,8 @@
1
+ class AnotherAdminSessionsController < ApplicationController
2
+ include Godmin::Authentication::SessionsController
3
+ include Godmin::Authentication
4
+
5
+ def admin_user_class
6
+ AnotherAdminUser
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ class CommentsController < ApplicationController
2
+ include Godmin::Resources::ResourceController
3
+ end
@@ -0,0 +1,7 @@
1
+ class AnotherAdminUser < ActiveRecord::Base
2
+ include Godmin::Authentication::User
3
+
4
+ def self.login_column
5
+ :email
6
+ end
7
+ end
@@ -1,5 +1,6 @@
1
1
  class Article < ActiveRecord::Base
2
2
  belongs_to :admin_user
3
+ has_many :comments
3
4
 
4
5
  def non_orderable_column
5
6
  "Not orderable"
@@ -0,0 +1,7 @@
1
+ class Comment < ActiveRecord::Base
2
+ belongs_to :article
3
+
4
+ def to_s
5
+ title
6
+ end
7
+ end
@@ -5,6 +5,8 @@ class ArticleService
5
5
  attrs_for_show :id, :title, :body, :admin_user, :published
6
6
  attrs_for_form :title, :body, :admin_user, :published
7
7
 
8
+ has_many :comments
9
+
8
10
  def order_by_admin_user(resources, direction)
9
11
  resources.joins(:admin_users).order("admin_users.email #{direction}")
10
12
  end
@@ -0,0 +1,7 @@
1
+ class CommentService
2
+ include Godmin::Resources::ResourceService
3
+
4
+ attrs_for_index :id, :title
5
+ attrs_for_show :id, :title, :body
6
+ attrs_for_form :title, :body
7
+ end
data/test/dummy/bin/rails CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
2
+ APP_PATH = File.expand_path('../config/application', __dir__)
3
3
  require_relative '../config/boot'
4
4
  require 'rails/commands'
@@ -1,23 +1,11 @@
1
- require File.expand_path('../boot', __FILE__)
1
+ require File.expand_path("../boot", __FILE__)
2
2
 
3
- require 'rails/all'
3
+ require "rails/all"
4
4
 
5
5
  Bundler.require(*Rails.groups)
6
6
  require "godmin"
7
7
 
8
8
  module Dummy
9
9
  class Application < Rails::Application
10
- # Settings in config/environments/* take precedence over those specified here.
11
- # Application configuration should go into files in config/initializers
12
- # -- all .rb files in that directory are automatically loaded.
13
-
14
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
15
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
16
- # config.time_zone = 'Central Time (US & Canada)'
17
-
18
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
- # config.i18n.default_locale = :de
21
10
  end
22
11
  end
23
-
@@ -0,0 +1,9 @@
1
+ en:
2
+ activerecord:
3
+ models:
4
+ article:
5
+ one: Article
6
+ other: Articles
7
+ comment:
8
+ one: Comment
9
+ other: Comments
@@ -1,8 +1,13 @@
1
1
  Rails.application.routes.draw do
2
- resources :articles
2
+ resources :articles do
3
+ resources :comments
4
+ end
3
5
  resources :authenticated_articles
4
6
  resources :authorized_articles
5
7
  resource :session, only: [:new, :create, :destroy]
8
+
9
+ resource :another_admin_session, only: [:create]
10
+
6
11
  root to: "application#welcome"
7
12
  mount Admin::Engine, at: "admin"
8
13
  end
@@ -1,4 +1,4 @@
1
- class CreateArticles < ActiveRecord::Migration
1
+ class CreateArticles < ActiveRecord::Migration[5.0]
2
2
  def change
3
3
  create_table :articles do |t|
4
4
  t.string :title
@@ -1,4 +1,4 @@
1
- class CreateAdminUsers < ActiveRecord::Migration
1
+ class CreateAdminUsers < ActiveRecord::Migration[5.0]
2
2
  def change
3
3
  create_table :admin_users do |t|
4
4
  t.string :email
@@ -0,0 +1,9 @@
1
+ class CreateComment < ActiveRecord::Migration[5.0]
2
+ def change
3
+ create_table :comments do |t|
4
+ t.references :article, index: true, foreign_key: true
5
+ t.string :title
6
+ t.text :body
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class CreateAnotherAdminUser < ActiveRecord::Migration[5.0]
2
+ def change
3
+ create_table :another_admin_users do |t|
4
+ t.string :email
5
+ t.text :password_digest
6
+
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -10,22 +10,37 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20150907133753) do
13
+ ActiveRecord::Schema.define(version: 20170207081043) do
14
14
 
15
15
  create_table "admin_users", force: :cascade do |t|
16
- t.string "email"
17
- t.text "password_digest"
18
- t.datetime "created_at", null: false
19
- t.datetime "updated_at", null: false
16
+ t.string "email"
17
+ t.text "password_digest"
18
+ t.datetime "created_at", null: false
19
+ t.datetime "updated_at", null: false
20
+ end
21
+
22
+ create_table "another_admin_users", force: :cascade do |t|
23
+ t.string "email"
24
+ t.text "password_digest"
25
+ t.datetime "created_at", null: false
26
+ t.datetime "updated_at", null: false
20
27
  end
21
28
 
22
29
  create_table "articles", force: :cascade do |t|
23
- t.string "title"
24
- t.text "body"
25
- t.boolean "published", default: false
26
- t.integer "admin_user_id"
27
- t.datetime "created_at", null: false
28
- t.datetime "updated_at", null: false
30
+ t.string "title"
31
+ t.text "body"
32
+ t.boolean "published", default: false
33
+ t.integer "admin_user_id"
34
+ t.datetime "created_at", null: false
35
+ t.datetime "updated_at", null: false
36
+ t.index ["admin_user_id"], name: "index_articles_on_admin_user_id"
37
+ end
38
+
39
+ create_table "comments", force: :cascade do |t|
40
+ t.integer "article_id"
41
+ t.string "title"
42
+ t.text "body"
43
+ t.index ["article_id"], name: "index_comments_on_article_id"
29
44
  end
30
45
 
31
46
  end
@@ -5,7 +5,7 @@ module Fakes
5
5
  end
6
6
 
7
7
  def self.column_names
8
- ["id", "title"]
8
+ %w[id title]
9
9
  end
10
10
  end
11
11
  end
@@ -13,8 +13,8 @@ module Fakes
13
13
  scope :published
14
14
 
15
15
  filter :title
16
- filter :country, as: :select, collection: %w(Sweden Canada)
17
- filter :tags, as: :multiselect, collection: %w(Apple Banana)
16
+ filter :country, as: :select, collection: %w[Sweden Canada]
17
+ filter :tags, as: :multiselect, collection: %w[Apple Banana]
18
18
 
19
19
  batch_action :unpublish
20
20
  batch_action :publish, confirm: true, only: [:unpublished], except: [:published]
@@ -24,12 +24,8 @@ module Fakes
24
24
  @called_methods = { scopes: {}, filters: {}, batch_actions: {}, ordering: {} }
25
25
  end
26
26
 
27
- def resource_class
28
- Fakes::Article
29
- end
30
-
31
27
  def resources_relation
32
- [:foo, :bar, :baz]
28
+ %i[foo bar baz]
33
29
  end
34
30
 
35
31
  def order_by_foobar(resources, direction)
@@ -0,0 +1,77 @@
1
+ require "test_helper"
2
+ require "generators/godmin/resource/resource_generator"
3
+
4
+ module Godmin
5
+ class ResourceGeneratorTest < ::Rails::Generators::TestCase
6
+ tests ResourceGenerator
7
+ destination File.expand_path("../../tmp", __FILE__)
8
+ setup :prepare_destination
9
+
10
+ def test_resource_generator_in_standalone_install
11
+ system "cd #{destination_root} && rails new . --skip-test --skip-spring --skip-bundle --skip-git --quiet"
12
+ system "cd #{destination_root} && bin/rails generate godmin:install --quiet"
13
+ system "cd #{destination_root} && bin/rails generate godmin:resource foo bar --quiet"
14
+
15
+ assert_file "config/routes.rb", /resources :foos/
16
+ assert_file "app/views/shared/_navigation.html.erb", /<%= navbar_item Foo %>/
17
+
18
+ assert_file "app/controllers/foos_controller.rb" do |content|
19
+ expected_content = <<-CONTENT.strip_heredoc
20
+ class FoosController < ApplicationController
21
+ include Godmin::Resources::ResourceController
22
+ end
23
+ CONTENT
24
+ assert_match expected_content, content
25
+ end
26
+
27
+ assert_file "app/services/foo_service.rb" do |content|
28
+ expected_content = <<-CONTENT.strip_heredoc
29
+ class FooService
30
+ include Godmin::Resources::ResourceService
31
+
32
+ attrs_for_index :bar
33
+ attrs_for_show :bar
34
+ attrs_for_form :bar
35
+ end
36
+ CONTENT
37
+ assert_match expected_content, content
38
+ end
39
+ end
40
+
41
+ def test_resource_generator_in_engine_install
42
+ system "cd #{destination_root} && rails new . --skip-test --skip-spring --skip-bundle --skip-git --quiet"
43
+ system "cd #{destination_root} && bin/rails plugin new fakemin --mountable --quiet"
44
+ system "cd #{destination_root} && fakemin/bin/rails generate godmin:install --quiet"
45
+ system "cd #{destination_root} && fakemin/bin/rails generate godmin:resource foo bar --quiet"
46
+
47
+ assert_file "fakemin/config/routes.rb", /resources :foos/
48
+ assert_file "fakemin/app/views/fakemin/shared/_navigation.html.erb", /<%= navbar_item Foo %>/
49
+
50
+ assert_file "fakemin/app/controllers/fakemin/foos_controller.rb" do |content|
51
+ expected_content = <<-CONTENT.strip_heredoc
52
+ module Fakemin
53
+ class FoosController < ApplicationController
54
+ include Godmin::Resources::ResourceController
55
+ end
56
+ end
57
+ CONTENT
58
+ assert_match expected_content, content
59
+ end
60
+
61
+ assert_file "fakemin/app/services/fakemin/foo_service.rb" do |content|
62
+ expected_content = <<-CONTENT.strip_heredoc
63
+ module Fakemin
64
+ class FooService
65
+ include Godmin::Resources::ResourceService
66
+
67
+ attrs_for_index :bar
68
+ attrs_for_show :bar
69
+ attrs_for_form :bar
70
+ end
71
+ end
72
+ CONTENT
73
+ assert_match expected_content, content
74
+ end
75
+ end
76
+ end
77
+ end
@@ -14,4 +14,12 @@ class AuthenticationTest < ActionDispatch::IntegrationTest
14
14
  visit authenticated_articles_path
15
15
  assert_not_equal authenticated_articles_path, current_path
16
16
  end
17
+
18
+ def test_sign_in_with_non_default_user
19
+ AnotherAdminUser.create!(email: "another_admin@example.com", password: "password")
20
+ post another_admin_session_path, params: {
21
+ another_admin_user: { email: "another_admin@example.com", password: "password" }
22
+ }
23
+ assert_redirected_to root_path
24
+ end
17
25
  end
@@ -29,4 +29,9 @@ class AuthorizationTest < ActionDispatch::IntegrationTest
29
29
  page.driver.delete authorized_article_path(article)
30
30
  assert_equal 403, page.status_code
31
31
  end
32
+
33
+ def test_cannot_index_in_engine?
34
+ visit admin.authorized_articles_path
35
+ assert_equal 403, page.status_code
36
+ end
32
37
  end
@@ -0,0 +1,47 @@
1
+ require "test_helper"
2
+
3
+ class NestedResourcesTest < ActionDispatch::IntegrationTest
4
+ def test_list_nested_resources
5
+ article = Article.create! title: "foo", comments: [
6
+ Comment.new(title: "bar")
7
+ ]
8
+
9
+ visit articles_path
10
+ within "[data-resource-id='#{article.id}']" do
11
+ click_link "Show"
12
+ end
13
+ click_link "Comments"
14
+
15
+ assert_equal article_comments_path(article), current_path
16
+ assert page.has_content? "bar"
17
+ end
18
+
19
+ def test_list_nested_resources_scoping
20
+ article = Article.create! title: "foo", comments: [
21
+ Comment.new(title: "bar")
22
+ ]
23
+ Comment.create! title: "baz"
24
+
25
+ visit article_comments_path(article)
26
+
27
+ assert page.has_content? "bar"
28
+ assert page.has_no_content? "baz"
29
+ end
30
+
31
+ def test_create_nested_resource
32
+ article = Article.create! title: "foo"
33
+
34
+ visit new_article_comment_path(article)
35
+
36
+ fill_in "Title", with: "bar"
37
+ click_button "Create Comment"
38
+
39
+ assert_equal article_comment_path(article, Comment.last), current_path
40
+
41
+ within "#breadcrumb" do
42
+ click_link "Comments"
43
+ end
44
+
45
+ assert page.has_content? "bar"
46
+ end
47
+ end
data/test/test_helper.rb CHANGED
@@ -1,8 +1,6 @@
1
- require "codeclimate-test-reporter"
2
- CodeClimate::TestReporter.start
3
-
4
1
  # Configure Rails Environment
5
2
  ENV["RAILS_ENV"] = "test"
3
+ ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"] = "1"
6
4
 
7
5
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
8
6
  require "rails/test_help"
@@ -11,7 +9,6 @@ require "capybara/poltergeist"
11
9
  require "minitest/reporters"
12
10
  require "pry"
13
11
 
14
- # TODO: what to call these?
15
12
  require File.expand_path("../fakes/article.rb", __FILE__)
16
13
  require File.expand_path("../fakes/article_service.rb", __FILE__)
17
14