rails-add_ons 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/app/assets/javascripts/rails/add_ons/application/acts-as-list.js.coffee +21 -0
  4. data/app/assets/javascripts/rails/add_ons/application.js +0 -2
  5. data/app/components/component/collection_table.rb +26 -2
  6. data/app/components/component/resource_table.rb +7 -1
  7. data/app/concerns/component/collection_table/acts_as_list_concern.rb +16 -0
  8. data/app/concerns/component/collection_table/acts_as_published_concern.rb +10 -0
  9. data/app/concerns/component/collection_table/batch_actions_concern.rb +12 -0
  10. data/app/concerns/component/collection_table/boolean_concern.rb +10 -0
  11. data/app/concerns/component/resource_table/boolean_concern.rb +10 -0
  12. data/app/concerns/resources_controller/acts_as_list_concern.rb +32 -0
  13. data/app/concerns/resources_controller/acts_as_published_concern.rb +73 -0
  14. data/app/concerns/resources_controller/awesome_nested_set_concern.rb +31 -0
  15. data/app/concerns/resources_controller/batch_actions_concern.rb +16 -0
  16. data/app/concerns/resources_controller/friendly_id_concern.rb +15 -0
  17. data/app/concerns/resources_controller/kaminari.rb +13 -11
  18. data/app/concerns/resources_controller/location_history.rb +31 -26
  19. data/app/concerns/resources_controller/pagination.rb +13 -11
  20. data/app/concerns/resources_controller/resource_inflections.rb +13 -11
  21. data/app/concerns/resources_controller/resources.rb +9 -7
  22. data/app/concerns/resources_controller/rest_actions.rb +77 -73
  23. data/app/concerns/resources_controller/rest_resource_urls.rb +25 -23
  24. data/app/concerns/resources_controller/sorting.rb +22 -14
  25. data/app/concerns/resources_controller/will_paginate.rb +14 -12
  26. data/app/concerns/service_controller/rest_actions.rb +15 -0
  27. data/app/helpers/rails/add_ons/table_helper.rb +10 -0
  28. data/app/views/component/_collection_table.haml +13 -12
  29. data/app/views/component/table/body_cells/_acts_as_list.haml +11 -0
  30. data/app/views/component/table/body_cells/_acts_as_published.haml +9 -0
  31. data/app/views/component/table/body_cells/_association.haml +5 -1
  32. data/app/views/component/table/body_cells/_batch_actions.haml +1 -0
  33. data/app/views/component/table/body_cells/_boolean.haml +4 -0
  34. data/app/views/component/table/header_cells/_batch_actions.haml +42 -0
  35. data/config/locales/de.yml +30 -1
  36. data/config/locales/en.yml +4 -1
  37. data/lib/generators/rails/add_ons/install_generator.rb +15 -0
  38. data/lib/generators/rails/add_ons/resources_controller_spec_generator.rb +53 -0
  39. data/lib/generators/rails/add_ons/templates/initializer.rb +7 -0
  40. data/lib/generators/rails/add_ons/templates/spec.rb +53 -0
  41. data/lib/rails/add_ons/configuration.rb +11 -0
  42. data/lib/rails/add_ons/shoulda/matchers/implement_create_action_matcher.rb +36 -4
  43. data/lib/rails/add_ons/shoulda/matchers/implement_update_action_matcher.rb +60 -17
  44. data/lib/rails/add_ons/version.rb +1 -1
  45. data/lib/rails/add_ons.rb +3 -2
  46. metadata +23 -2
@@ -1,91 +1,95 @@
1
- module ResourcesController::RestActions
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- include ActionController::MimeResponds
6
-
7
- respond_to :html
8
- responders :flash
9
-
10
- if respond_to?(:before_action)
11
- before_action :load_collection, only: [:index]
12
- before_action :load_resource, only: [:show, :edit, :destroy, :update]
13
- before_action :initialize_resource, only: [:new]
14
- before_action :initialize_resource_for_create, only: [:create]
15
- else
16
- before_filter :load_collection, only: [:index]
17
- before_filter :load_resource, only: [:show, :edit, :destroy, :update]
18
- before_filter :initialize_resource, only: [:new]
19
- before_filter :initialize_resource_for_create, only: [:create]
20
- end
21
- end
1
+ module ResourcesController
2
+ module RestActions
3
+ extend ActiveSupport::Concern
22
4
 
23
- def index; end
24
- def new; end
25
- def show; end
26
- def edit; end
5
+ included do
6
+ include ActionController::MimeResponds
27
7
 
28
- def update
29
- if Rails::VERSION::MAJOR < 4
30
- @resource.update_attributes(permitted_params)
31
- else
32
- @resource.update(permitted_params)
8
+ respond_to :html
9
+ responders :flash
10
+
11
+ if respond_to?(:before_action)
12
+ before_action :load_collection, only: [:index]
13
+ before_action :load_resource, only: [:show, :edit, :destroy, :update]
14
+ before_action :initialize_resource, only: [:new]
15
+ before_action :initialize_resource_for_create, only: [:create]
16
+ else
17
+ before_filter :load_collection, only: [:index]
18
+ before_filter :load_resource, only: [:show, :edit, :destroy, :update]
19
+ before_filter :initialize_resource, only: [:new]
20
+ before_filter :initialize_resource_for_create, only: [:create]
21
+ end
33
22
  end
34
- if respond_to?(:after_update_location, true)
35
- respond_with(respond_with_namespace, @resource, location: after_update_location)
36
- else
37
- respond_with(respond_with_namespace, @resource)
23
+
24
+ def index; end
25
+ def new; end
26
+ def show; end
27
+ def edit; end
28
+
29
+ def update
30
+ if Rails::VERSION::MAJOR < 4
31
+ @resource.update_attributes(permitted_params)
32
+ else
33
+ @resource.update(permitted_params)
34
+ end
35
+
36
+ if respond_to?(:after_update_location, true)
37
+ respond_with(respond_with_namespace, @resource, location: after_update_location)
38
+ else
39
+ respond_with(respond_with_namespace, @resource)
40
+ end
38
41
  end
39
- end
40
42
 
41
- def destroy
42
- @resource.destroy
43
- if respond_to?(:after_destroy_location, true)
44
- respond_with(respond_with_namespace, @resource, location: after_destroy_location)
45
- else
46
- respond_with(respond_with_namespace, @resource)
43
+ def destroy
44
+ @resource.destroy
45
+ if respond_to?(:after_destroy_location, true)
46
+ respond_with(respond_with_namespace, @resource, location: after_destroy_location)
47
+ else
48
+ respond_with(respond_with_namespace, @resource)
49
+ end
47
50
  end
48
- end
49
51
 
50
- def create
51
- @resource.save
52
- if respond_to?(:after_create_location, true)
53
- respond_with(respond_with_namespace, @resource, location: after_create_location)
54
- else
55
- respond_with(respond_with_namespace, @resource)
52
+ def create
53
+ @resource.save
54
+ if respond_to?(:after_create_location, true)
55
+ respond_with(respond_with_namespace, @resource, location: after_create_location)
56
+ else
57
+ respond_with(respond_with_namespace, @resource)
58
+ end
56
59
  end
57
- end
58
60
 
59
- private
61
+ private
60
62
 
61
- def respond_with_namespace
62
- nil
63
- end
63
+ def respond_with_namespace
64
+ nil
65
+ end
64
66
 
65
- def load_collection_scope
66
- resource_class
67
- end
67
+ def load_collection_scope
68
+ resource_class
69
+ end
68
70
 
69
- def load_collection
70
- @collection = load_collection_scope.all
71
- end
71
+ def load_collection
72
+ @collection = load_collection_scope.all
73
+ end
72
74
 
73
- def load_resource_scope
74
- resource_class
75
- end
76
- def load_resource
77
- @resource = load_resource_scope.find(params[:id])
78
- end
75
+ def load_resource_scope
76
+ resource_class
77
+ end
79
78
 
80
- def initialize_resource
81
- @resource = resource_class.new
82
- end
79
+ def load_resource
80
+ @resource = load_resource_scope.find(params[:id])
81
+ end
83
82
 
84
- def initialize_resource_for_create
85
- @resource = resource_class.new(permitted_params)
86
- end
83
+ def initialize_resource
84
+ @resource = resource_class.new
85
+ end
87
86
 
88
- def permitted_params
89
- raise "not implemented"
87
+ def initialize_resource_for_create
88
+ @resource = resource_class.new(permitted_params)
89
+ end
90
+
91
+ def permitted_params
92
+ raise "not implemented"
93
+ end
90
94
  end
91
95
  end
@@ -1,32 +1,34 @@
1
- module ResourcesController::RestResourceUrls
2
- extend ActiveSupport::Concern
1
+ module ResourcesController
2
+ module RestResourceUrls
3
+ extend ActiveSupport::Concern
3
4
 
4
- included do
5
- helper_method :new_resource_path
6
- helper_method :collection_path
7
- helper_method :resource_path
8
- helper_method :edit_resource_path
9
- end
5
+ included do
6
+ helper_method :new_resource_path
7
+ helper_method :collection_path
8
+ helper_method :resource_path
9
+ helper_method :edit_resource_path
10
+ end
10
11
 
11
- private
12
+ private
12
13
 
13
- def new_resource_path
14
- resource_router.send(:url_for, { action: :new, only_path: true })
15
- end
14
+ def new_resource_path
15
+ resource_router.send(:url_for, { action: :new, only_path: true })
16
+ end
16
17
 
17
- def collection_path
18
- resource_router.send(:url_for, { action: :index, only_path: true })
19
- end
18
+ def collection_path
19
+ resource_router.send(:url_for, { action: :index, only_path: true })
20
+ end
20
21
 
21
- def resource_path(resource)
22
- resource_router.send(:url_for, { action: :show, id: resource, only_path: true })
23
- end
22
+ def resource_path(resource)
23
+ resource_router.send(:url_for, { action: :show, id: resource, only_path: true })
24
+ end
24
25
 
25
- def edit_resource_path(resource)
26
- resource_router.send(:url_for, { action: :edit, id: resource, only_path: true })
27
- end
26
+ def edit_resource_path(resource)
27
+ resource_router.send(:url_for, { action: :edit, id: resource, only_path: true })
28
+ end
28
29
 
29
- def resource_router
30
- self
30
+ def resource_router
31
+ self
32
+ end
31
33
  end
32
34
  end
@@ -1,20 +1,28 @@
1
- module ResourcesController::Sorting
2
- private
1
+ module ResourcesController
2
+ module Sorting
3
+ private
3
4
 
4
- def load_collection_scope
5
- add_order_scope(super)
6
- end
5
+ def load_collection_scope
6
+ add_order_scope(super)
7
+ end
7
8
 
8
- def add_order_scope(base_scope)
9
- if params[:sort_by].present?
10
- if params[:sort_by].include?(' ') || params[:sort_direction].include?(' ')
11
- raise "Possible SQL Injection attempt while trying to sort by #{params[:sort_by]} #{params[:sort_direction]}"
12
- end
9
+ def add_order_scope(base_scope)
10
+ if params[:sort_by].present?
11
+ if params[:sort_by].include?(' ') || params[:sort_direction].include?(' ')
12
+ raise "Possible SQL Injection attempt while trying to sort by #{params[:sort_by]} #{params[:sort_direction]}"
13
+ end
13
14
 
14
- sort_direction = (params[:sort_direction] || :asc)
15
- base_scope.reorder("#{params[:sort_by]} #{sort_direction}")
16
- else
17
- base_scope
15
+ sort_by = params[:sort_by]
16
+ sort_direction = (params[:sort_direction] || :asc)
17
+
18
+ if sort_by.include?('.')
19
+ base_scope.reorder("#{sort_by} #{sort_direction}")
20
+ else
21
+ base_scope.reorder(sort_by => sort_direction)
22
+ end
23
+ else
24
+ base_scope
25
+ end
18
26
  end
19
27
  end
20
28
  end
@@ -1,17 +1,19 @@
1
- module ResourcesController::WillPaginate
2
- extend ActiveSupport::Concern
1
+ module ResourcesController
2
+ module WillPaginate
3
+ extend ActiveSupport::Concern
3
4
 
4
- included do
5
- helper_method :paginate?
6
- end
5
+ included do
6
+ helper_method :paginate?
7
+ end
7
8
 
8
- def paginate?
9
- true
10
- end
9
+ def paginate?
10
+ true
11
+ end
11
12
 
12
- private
13
+ private
13
14
 
14
- def load_collection
15
- @collection = load_collection_scope.paginate(page: params[:page])
15
+ def load_collection
16
+ @collection = load_collection_scope.paginate(page: params[:page])
17
+ end
16
18
  end
17
- end
19
+ end
@@ -62,6 +62,21 @@ module ServiceController::RestActions
62
62
  @service = service_class.new({}, service_options)
63
63
  end
64
64
 
65
+ # Override this method in your child class to manipulate your service before
66
+ # it performs.
67
+ #
68
+ # Example:
69
+ # # app/controller/import_services_controller.rb
70
+ # class ImportServices < ApplicationServicesController
71
+ # #...
72
+ # private
73
+ #
74
+ # def initialize_service_for_create
75
+ # super
76
+ # @service.current_user_id = session['current_user_id']
77
+ # end
78
+ # end
79
+ #
65
80
  def initialize_service_for_create
66
81
  @service = service_class.new(hashified_params, service_options)
67
82
  end
@@ -1,5 +1,15 @@
1
1
  module Rails
2
2
  module AddOns
3
+ # Provides helpers to render tables for collections and single resources.
4
+ # To use it you have to add it to your controller:
5
+ #
6
+ # Example:
7
+ #
8
+ # class PostsController < ApplicationController
9
+ # #...
10
+ # helper Rails::AddOns::TableHelper
11
+ # end
12
+ #
3
13
  module TableHelper
4
14
  def collection_table(options = {}, &block)
5
15
  Component::CollectionTable.new(self, options, &block).perform
@@ -1,17 +1,18 @@
1
1
  %table{ class: table_css_classes }
2
- %thead
3
- %tr
4
- - columns.each do |name, options|
5
- - title = options.delete(:title)
6
- - if title.nil?
7
- - if resource_class.respond_to?(:human_attribute_name)
8
- - title = resource_class.human_attribute_name(name)
2
+ - if show_header
3
+ %thead
4
+ %tr
5
+ - columns.each do |name, options|
6
+ - title = options.delete(:title)
7
+ - if title.nil?
8
+ - if resource_class.respond_to?(:human_attribute_name)
9
+ - title = resource_class.human_attribute_name(name)
10
+ - else
11
+ - title = name
12
+ - if options.has_key?(:sort)
13
+ %td= sort_link(name, title, options[:sort])
9
14
  - else
10
- - title = name
11
- - if options.has_key?(:sort)
12
- %td= sort_link(name, title, options[:sort])
13
- - else
14
- %td= title
15
+ %td= title
15
16
  %tbody
16
17
  - collection.each do |resource|
17
18
  - tr_options = { class: resource_class.name.underscore.gsub('/', '-') }
@@ -0,0 +1,11 @@
1
+ :ruby
2
+ scope = options.delete(:scope)
3
+ data_attributes = {
4
+ 'acts-as-list-item': true,
5
+ 'acts-as-list-item-uid': resource.to_param,
6
+ 'acts-as-list-item-on-drop-target': url_for([:reposition, resource])
7
+ }
8
+ data_attributes['acts-as-list-item-scope'] = "#{scope}-#{resource.send(scope)}" if scope.present?
9
+
10
+ %span.btn.btn-xs.btn-default.acts-as-list-item{ data: data_attributes }
11
+ %span.glyphicon.glyphicon-sort.fas.fa-sort
@@ -0,0 +1,9 @@
1
+ - link_path = controller.url_for(action: :toggle_published, id: resource.to_param)
2
+ - if resource.published?
3
+ = button_to(link_path, class: 'btn btn-xs btn-danger btn-responsive', method: :post) do
4
+ %span.glyphicon.glyphicon-eye-close
5
+ %span.btn-text= t('.unpublish', default: t('acts_as_published.actions.unpublish'))
6
+ - else
7
+ = button_to(link_path, class: 'btn btn-xs btn-success btn-responsive', method: :post) do
8
+ %span.glyphicon.glyphicon-eye-open
9
+ %span.btn-text= t('.publish', default: t('acts_as_published.actions.publish'))
@@ -1,5 +1,9 @@
1
1
  - label = if options[:label_method].present?
2
- - resource.send(name).try(options[:label_method])
2
+ - case options[:label_method]
3
+ - when Proc
4
+ - options[:label_method].call(resource.send(name))
5
+ - else
6
+ - resource.send(name).try(options[:label_method])
3
7
  - else
4
8
  - resource.send(name)
5
9
  - link_to = options[:link_to]
@@ -0,0 +1 @@
1
+ = check_box_tag "ids[]", resource.id, false, class: 'batch-action-checkbox'
@@ -0,0 +1,4 @@
1
+ - if resource.send(name)
2
+ = t('.true')
3
+ - else
4
+ = t('.false')
@@ -0,0 +1,42 @@
1
+ :css
2
+ #batch-action-dropdown {
3
+ display: none;
4
+ }
5
+
6
+ %form{ method: 'post', id: 'batch-action-form' }
7
+ = hidden_field_tag :authenticity_token, form_authenticity_token
8
+ .dropdown.batch-action-dropdown
9
+ %button.btn.btn-default.dropdown-toggle{"aria-expanded" => "true", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button", id: 'batch-action-dropdown' }
10
+ = t('.batch_actions')
11
+ %span.caret
12
+ %ul.dropdown-menu{"aria-labelledby" => 'batch-action-dropdown' }
13
+ - options[:actions].each do |action, target|
14
+ %li
15
+ %a{ href: target, class: 'batch-action-form-submit-link' }= t(".#{action}")
16
+
17
+ :javascript
18
+ $(document).ready(function() {
19
+ $('.batch-action-checkbox').click(function() {
20
+ var check_count = $('.batch-action-checkbox:checked').size();
21
+ if( check_count > 0 ) {
22
+ $("#batch-action-dropdown").show();
23
+ } else {
24
+ $("#batch-action-dropdown").hide();
25
+ }
26
+ });
27
+
28
+ $('#batch-action-form').submit(function() {
29
+ $('#batch-action-form input:checked').remove();
30
+ var selected_items = $('.batch-action-checkbox:checked').clone();
31
+ selected_items.css('display', 'none');
32
+ $('#batch-action-form').append(selected_items);
33
+ return true;
34
+ });
35
+
36
+ $('.batch-action-form-submit-link').click(function(e) {
37
+ e.preventDefault();
38
+ var target = $(this).attr('href');
39
+ $("#batch-action-form").attr("action", target);
40
+ $('#batch-action-form').submit();
41
+ });
42
+ });
@@ -4,10 +4,20 @@ de:
4
4
  component:
5
5
  collection_table:
6
6
  column_titles:
7
- awesome_nested_set: Sortieren
7
+ acts_as_list: Sortierung
8
+ acts_as_published: Veröffentlichung
9
+ awesome_nested_set: Sortierung
8
10
  delete: Löschen
9
11
  edit: Bearbeiten
10
12
  show: Anzeigen
13
+ table:
14
+ body_cells:
15
+ boolean:
16
+ 'true': Ja
17
+ 'false': Nein
18
+ header_cells:
19
+ batch_actions:
20
+ destroy: Löschen
11
21
  flash:
12
22
  actions:
13
23
  create:
@@ -20,6 +30,25 @@ de:
20
30
  perform:
21
31
  notice: "%{resource_name} wurde ausgeführt."
22
32
  alert: "%{resource_name} konnte nicht ausgeführt werden. Es traten folgende Fehler auf: %{errors}"
33
+ acts_as_list:
34
+ flash:
35
+ actions:
36
+ reposition:
37
+ inserted_after: "%{inserted_resource} nach %{target_resource} eingefügt"
38
+ inserted_before: "%{inserted_resource} vor %{target_resource} eingefügt"
39
+ acts_as_published:
40
+ flash:
41
+ actions:
42
+ toggle_published:
43
+ published:
44
+ notice: "%{resource_name} veröffentlicht."
45
+ unpublished:
46
+ notice: "%{resource_name} zurückgezogen."
47
+ awesome_nested_set:
48
+ flash:
49
+ actions:
50
+ reposition:
51
+ notice: "%{inserted_resource} nach %{target_resource} eingefügt"
23
52
  i18n:
24
53
  locales:
25
54
  en: English
@@ -3,7 +3,10 @@ en:
3
3
  i18n: Language
4
4
  component:
5
5
  collection_table:
6
- delete: Delete
6
+ column_titles:
7
+ acts_as_published: Publishing
8
+ awesome_nested_set: Sorting
9
+ destroy: Delete
7
10
  edit: Edit
8
11
  show: Show
9
12
  flash:
@@ -0,0 +1,15 @@
1
+ module Rails
2
+ module AddOns
3
+ module Generators
4
+ class InstallGenerator < Rails::Generators::Base
5
+ desc 'Generates the initializer'
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def generate_initializer
10
+ template 'initializer.rb', 'config/initializers/rails-add_ons.rb'
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,53 @@
1
+ module Rails
2
+ module AddOns
3
+ # This will generate specs for create, read, update, delete and list.
4
+ #
5
+ # Example:
6
+ #
7
+ # rails g rails:add_ons:resources_controller_spec --uri /de/backend/uploads
8
+ # create spec/features/de/backend/uploads_feature_spec.rb
9
+ #
10
+ # If your resource class does not match the last part of your url (i.e.
11
+ # /de/posts would guess the resource class to Post) you can specify the resource
12
+ # name like this:
13
+ #
14
+ # RESOURCE_CLASS=Blog::Post rails g rails:add_ons:resources_controller_spec --uri /de/posts
15
+ # create spec/features/de/posts_feature_spec.rb
16
+ #
17
+ class ResourcesControllerSpecGenerator < Rails::Generators::Base
18
+ desc 'Generates CRUDL specs for REST resources'
19
+
20
+ source_root File.expand_path('../templates', __FILE__)
21
+
22
+ class_option :uri, type: :string, required: true
23
+
24
+ def uri
25
+ @uri ||= options['uri']
26
+ end
27
+
28
+ def edit_form_dom_selector
29
+ ".edit_#{resource_class.demodulize.underscore}"
30
+ end
31
+
32
+ def new_form_dom_selector
33
+ "#new_#{resource_class.demodulize.underscore}"
34
+ end
35
+
36
+ def resource_class
37
+ @resource_class ||= ENV.fetch('RESOURCE_CLASS') { @uri.split('/').last.camelize.singularize }
38
+ end
39
+
40
+ def factory_name
41
+ underscored_resource_class
42
+ end
43
+
44
+ def underscored_resource_class
45
+ @undescored_resource_class ||= resource_class.underscore.gsub('/', '_')
46
+ end
47
+
48
+ def generate_spec
49
+ template 'spec.rb', "spec/features#{uri}_feature_spec.rb"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+ Rails::AddOns.configure do |config|
2
+ # Set the default format for timestamps in tables.
3
+ #
4
+ # Default: config.table_default_timestamp_format = nil
5
+ #
6
+ config.table_default_timestamp_format = nil
7
+ end
@@ -0,0 +1,53 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe '<%= uri %>', type: :feature do
4
+ let(:resource_class) { <%= resource_class %> }
5
+ let(:resource) { create(:<%= factory_name %>) }
6
+ let(:resources) { create_list(:<%= factory_name %>, 3) }
7
+
8
+ # List
9
+ it { resources; expect(subject).to implement_index_action(self) }
10
+
11
+ # Create
12
+ it {
13
+ expect(subject).to implement_create_action(self)
14
+ .for(resource_class)
15
+ .within_form('<%= new_form_dom_selector %>') {
16
+ # fill the needed form inputs via capybara here
17
+ #
18
+ # Example:
19
+ #
20
+ # select 'de', from: 'slider[locale]'
21
+ # fill_in 'slider[name]', with: 'My first slider'
22
+ # check 'slider[auto_start]'
23
+ # fill_in 'slider[interval]', with: '3'
24
+ }
25
+ .increasing{ <%= resource_class %>.count }.by(1)
26
+ }
27
+
28
+ # Read
29
+ it { expect(subject).to implement_show_action(self).for(resource) }
30
+
31
+ # Update
32
+ it {
33
+ expect(subject).to implement_update_action(self)
34
+ .for(resource)
35
+ .within_form('<%= edit_form_dom_selector %>') {
36
+ # fill the needed form inputs via capybara here
37
+ #
38
+ # Example:
39
+ #
40
+ # fill_in 'slider[name]', with: 'New name'
41
+ }
42
+ .updating
43
+ .from(resource.attributes)
44
+ .to({ }) # Example: .to({ 'name' => 'New name' })
45
+ }
46
+
47
+ # Delete
48
+ it {
49
+ expect(subject).to implement_delete_action(self)
50
+ .for(resource)
51
+ .reducing{ resource_class.count }.by(1)
52
+ }
53
+ end
@@ -0,0 +1,11 @@
1
+ module Rails
2
+ module AddOns
3
+ module Configuration
4
+ def configure
5
+ yield self
6
+ end
7
+
8
+ mattr_accessor(:table_default_timestamp_format) { :short }
9
+ end
10
+ end
11
+ end