pax_global_header00006660000000000000000000000064140452603520014513gustar00rootroot0000000000000052 comment=b7bb90e756d7af11a9bf8d1878dfcc5a271b30a4 inherited_resources-1.13.0/000077500000000000000000000000001404526035200156425ustar00rootroot00000000000000inherited_resources-1.13.0/.github/000077500000000000000000000000001404526035200172025ustar00rootroot00000000000000inherited_resources-1.13.0/.github/FUNDING.yml000066400000000000000000000000541404526035200210160ustar00rootroot00000000000000--- tidelift: rubygems/inherited_resources inherited_resources-1.13.0/.github/dependabot.yml000066400000000000000000000006471404526035200220410ustar00rootroot00000000000000--- version: 2 updates: - package-ecosystem: bundler directory: / schedule: interval: daily versioning-strategy: lockfile-only - package-ecosystem: bundler directory: /test/rails_60 schedule: interval: daily versioning-strategy: lockfile-only - package-ecosystem: bundler directory: /test/rails_52 schedule: interval: daily versioning-strategy: lockfile-only inherited_resources-1.13.0/.github/mergify.yml000066400000000000000000000014231404526035200213670ustar00rootroot00000000000000--- pull_request_rules: - name: Automatic merge for dependabot pull requests conditions: - author~=^dependabot(|-preview)\[bot\]$ - check-success=lint - check-success=test(ruby-2.5, rails_52) - check-success=test(ruby-2.5, rails_60) - check-success=test(ruby-2.5, rails_61) - check-success=test(ruby-2.6, rails_52) - check-success=test(ruby-2.6, rails_60) - check-success=test(ruby-2.6, rails_61) - check-success=test(ruby-2.7, rails_52) - check-success=test(ruby-2.7, rails_60) - check-success=test(ruby-2.7, rails_61) - check-success=test(jruby-9.2, rails_52) - check-success=test(jruby-9.2, rails_60) - check-success=test(jruby-9.2, rails_61) actions: merge: method: merge inherited_resources-1.13.0/.github/workflows/000077500000000000000000000000001404526035200212375ustar00rootroot00000000000000inherited_resources-1.13.0/.github/workflows/ci.yaml000066400000000000000000000034661404526035200225270ustar00rootroot00000000000000--- name: ci on: pull_request: push: branches: - master jobs: lint: runs-on: ubuntu-20.04 timeout-minutes: 15 strategy: fail-fast: false steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: 3.0.1 bundler-cache: true - name: Make sure gemfiles are up to date run: ruby -Itest -rbundler/setup -rgemfiles/lint -e 'exit(Minitest.run)' - name: Make sure gemspec builds without warnings run: ruby -Itest -rbundler/setup -rgemfiles/gemspec_lint -e 'exit(Minitest.run)' - name: Run linters run: bin/rubocop test: name: test (${{ matrix.ruby.name }}, ${{ matrix.rails }}) runs-on: ubuntu-20.04 timeout-minutes: 15 strategy: fail-fast: false matrix: ruby: - { name: ruby-2.5, value: 2.5.9 } - { name: ruby-2.6, value: 2.6.7 } - { name: ruby-2.7, value: 2.7.3 } - { name: ruby-3.0, value: 3.0.1 } - { name: jruby-9.2, value: jruby-9.2.17.0 } rails: [rails_52, rails_60, rails_61] exclude: - ruby: { name: ruby-3.0, value: 3.0.1 } rails: rails_52 env: COVERAGE: true steps: - uses: actions/checkout@v2 - name: Configure bundler (default) run: | echo "BUNDLE_GEMFILE=Gemfile" >> $GITHUB_ENV if: matrix.rails == 'rails_61' - name: Configure bundler (alternative) run: | echo "BUNDLE_GEMFILE=test/${{ matrix.rails }}/Gemfile" >> $GITHUB_ENV if: matrix.rails != 'rails_61' - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby.value }} bundler-cache: true - name: Run tests run: bundle exec rake test TESTOPTS="--verbose" inherited_resources-1.13.0/.gitignore000066400000000000000000000000141404526035200176250ustar00rootroot00000000000000.bundle pkg inherited_resources-1.13.0/.rubocop.yml000066400000000000000000000012761404526035200201220ustar00rootroot00000000000000--- AllCops: DisabledByDefault: true DisplayCopNames: true DisplayStyleGuide: true TargetRubyVersion: 2.5 Metrics: Enabled: false Layout/CommentIndentation: Enabled: true Layout/EndAlignment: EnforcedStyleAlignWith: variable Enabled: true Layout/EmptyLines: Enabled: true Layout/EmptyLinesAroundAccessModifier: Enabled: true Layout/EmptyLinesAroundClassBody: Enabled: true Layout/IndentationConsistency: Enabled: true EnforcedStyle: indented_internal_methods Layout/IndentationWidth: Enabled: true Layout/IndentationStyle: Enabled: true Layout/TrailingWhitespace: Enabled: true Layout/TrailingEmptyLines: Enabled: true Style/HashSyntax: Enabled: true inherited_resources-1.13.0/CHANGELOG.md000066400000000000000000000167271404526035200174700ustar00rootroot00000000000000# Changelog ## Master (unreleased) ## Version 1.13.0 * Remove support for Ruby `< 2.5`. * Coerce `:route_prefix` config option to a Symbol, ensuring compatibility with Rails versions that have resolved CVE-2021-22885. ## Version 1.12.0 * Remove support for Rails 5.0 and Rails 5.1. * Allow using Rails 6.1. ## Version 1.11.0 * Add support for responders `>= 3.0`. * Remove support for Ruby `< 2.4`. ## Version 1.10.0 _No changes_. ## Version 1.10.0.rc1 * Preliminary support for Rails 6.0. * Remove support for Rails 4.2. ## Version 1.9.0 * Support Rails 5.2.1. * Remove support for Ruby `< 2.3`. ## Version 1.8.0 * Support Rails 5.2. * Supports Ruby 2.4. * Remove support for Ruby `< 2.2`, and Rails `< 4.2`. * Fixed broken class name in belongs_to. * Remove use of HttpCacheResponder. * Correct request_name in isolated engines. * Fix nested controllers and singleton option. ## Version 1.7.2 * Support Rails 5.1. ## Version 1.7.1 * Fix regression with `get_resource_ivar` that was returning `false` instead of `nil` when the value was not set. * Do not load `ActionController::Base` on boot time. ## Version 1.7.0 * Support Rails 5. * Remove support for Ruby `< 2.1`. * Fix URL helpers on mountable engines. * Allow support to has_scope `< 0.6` and `> 1.0`. Users are now able to choose which version they want to use in their applications. ## Version 1.6.0 * Support Rails 4.2. ## Version 1.5.1 * Lock the Rails version until only 4.2. * Fix parent class lookup. * Fix resource_class default value definition. ## Version 1.5.0 * Supports nested modules (namespaced models and controllers). * Supports Rails 4 Strong Parameters notation. ## Version 1.4.1 * Supports Rails 4. * Improved compatability with strong params. ## Version 1.4.0 * Supports Ruby 2.0.0. * Added support for the strong_parameters gem. See the README for more. * Added the ability to pass without_protection when creating/updating. * Fixed multi-level nested singletons. * Correct paths now generated for uncountable shallow resources. ## Version 1.3.1 * Fix polymorphic_belongs_to to get the parent. * Added support for Rails 3.2. * Added support to responders >= 0.6.0. ## Version 1.3.0 * Added support for multiple polymorphic optional nesting. * Fix nested namespace in mountable apps. * Added support for rails 3.1 new mass assignment conventions. * Turn InheritedResources::Base into a reloadable constant to fix reloading issues. ## Version 1.2.2 * Fix a bug in params parsing. * Call .scoped only if it is available. ## Version 1.2.1 * Fix a bug with namespaces. * Use Post.scoped instead of Post.all in collection. ## Version 1.2 * Improved lookup for namespaces (by github.com/Sirupsen). * Support to custom actions (by github.com/lda). * Rails 3.1 compatibility (by github.com/etehtsea). ## Version 1.1 * Rails 3 compatible. ## Version 1.0 * responders was removed from InheritedResources core and is a dependency. To install it, please do: sudo gem install responders * has_scope was removed from InheritedResources core and is now available as a standalone gem. To install it, please do: sudo gem install has_scope ## Version 0.9 * Allow dual blocks in destroy. * Added :if and :unless to has_scope (thanks to Jack Danger). * Added create_resource, update_resource and delete_resource hooks (thanks to Carlos Antonio da Silva). * Backported ActionController::Responder from Rails 3. * Added parent_url helper. * Added association_chain helper (as suggested by http://github.com/emmanuel). ## Version 0.8 * Fixed a small bug on optional belongs to with namespaced controllers. * Allow a parameter to be given to collection_url in polymorphic cases to replace the parent. * Allow InheritedResources to be called without inheritance. * Ensure that controllers that inherit from a controller with InheritedResources works properly. ## Version 0.7 * Allow procs as default value in has scope to be able to use values from session, for example. * Allow blocks with arity 0 or -1 to be given as the redirect url: def destroy destroy!{ project_url(@project) } end * Allow interpolation_options to be set in the application controller. * Added has_scope to controller (an interface for named_scopes). * Added polymorphic_belongs_to, optional_belongs_to and singleton_belongs_to as quick methods. * Only load belongs_to, singleton and polymorphic helpers if they are actually required. base_helpers, class_methods, dumb_responder and url_helpers are loaded when you inherited from base for the first time. # Version 0.6 * Ensure that the default template is not rendered if the default_template_format is not accepted. This is somehow related with the security breach report: http://www.rorsecurity.info/journal/2009/4/24/hidden-actions-render-templates.html IR forbids based on mime types. For example: respond_to :html, :except => :index ensures that the index.html.erb view is not rendered, making your IR controllers safer. * Fixed a bug that happens only when format.xml is given to blocks and then it acts as default, instead of format.html. * Fixed a strange bug where when you have create.html.erb or update.html.erb, it makes IE6 and IE7 return unprocessable entity (because they send Mime::ALL). * Stop rescueing any error when constantizing the resource class and allow route_prefix to be nil. * Cleaned up tests and responder structure. Whenever you pass a block to aliases and this block responds to the request, the other blocks are not parsed improving performance. * [BACKWARDS INCOMPATIBLE] By default, Inherited Resources respond only :html requests. * Added a quick way to overwrite the redirect to url in :create, :update and :destroy. ## Version 0.5 * Decoupled routes name from :instance_name and :collection_name. This way we have more flexibility. Use route_instance_name and route_collection_name to to change routes. * Avoid calling human_name on nil when a resource class is not defined. * Only call I18n if it's defined. ## Version 0.4 * Dealing with namespaced controllers out of the box. * Added support to namespaced routes through :route_prefix. * Added fix when resource_url is not defined. * Added better handling for namespaced controllers. * Added flash messages scoped by namespaced controllers. * Deprecated {{resource}} in I18n, use {{resource_name}} instead. * rspec bug fix is not automatically required anymore. User has to do it explicitly. * Added a file which fix a rspec bug when render is called inside a method which receives a block. * parent? does not take begin_of_association_chain into account anymore. * Added options to url helpers. * Added :optional to belongs_to associations. It allows you to deal with categories/1/products/2 and /products/2 with just one controller. * Cleaned up tests. ## Version 0.3 * Minor bump after three bug fixes. * Bug fix when showing warning of constant redefinition. * Bug fix with ApplicationController not being unloaded properly on development. * Bug fix when having root singleton resources. Calling `collection_url` would raise "NoMethodError \_url", not it will call root_url. * More comments on UrlHelpers. ## Version 0.2 * Bug fix when ApplicationController is already loaded when we load respond_to. * Added support success/failure blocks. * Eager loading of files to work properly in multithreaded environments. ## Version 0.1 * Added more helper_methods. * Added Rails 2.3.0 and changed tests to work with ActionController::TestCase. * First release. Support to I18n, singleton controllers, polymorphic controllers, belongs_to, nested_belongs_to and url helpers. inherited_resources-1.13.0/Gemfile000066400000000000000000000003151404526035200171340ustar00rootroot00000000000000source 'https://rubygems.org' gemspec path: '.' group :development do gem 'rails', '~> 6.1.3.a' gem 'mocha' gem 'minitest-rg' gem 'rails-controller-testing' gem 'rubocop' gem 'chandler' end inherited_resources-1.13.0/Gemfile.lock000066400000000000000000000122211404526035200200620ustar00rootroot00000000000000PATH remote: . specs: inherited_resources (1.13.0) actionpack (>= 5.2, < 6.2) has_scope (~> 0.6) railties (>= 5.2, < 6.2) responders (>= 2, < 4) GEM remote: https://rubygems.org/ specs: actioncable (6.1.3.2) actionpack (= 6.1.3.2) activesupport (= 6.1.3.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) actionmailbox (6.1.3.2) actionpack (= 6.1.3.2) activejob (= 6.1.3.2) activerecord (= 6.1.3.2) activestorage (= 6.1.3.2) activesupport (= 6.1.3.2) mail (>= 2.7.1) actionmailer (6.1.3.2) actionpack (= 6.1.3.2) actionview (= 6.1.3.2) activejob (= 6.1.3.2) activesupport (= 6.1.3.2) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) actionpack (6.1.3.2) actionview (= 6.1.3.2) activesupport (= 6.1.3.2) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) actiontext (6.1.3.2) actionpack (= 6.1.3.2) activerecord (= 6.1.3.2) activestorage (= 6.1.3.2) activesupport (= 6.1.3.2) nokogiri (>= 1.8.5) actionview (6.1.3.2) activesupport (= 6.1.3.2) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) activejob (6.1.3.2) activesupport (= 6.1.3.2) globalid (>= 0.3.6) activemodel (6.1.3.2) activesupport (= 6.1.3.2) activerecord (6.1.3.2) activemodel (= 6.1.3.2) activesupport (= 6.1.3.2) activestorage (6.1.3.2) actionpack (= 6.1.3.2) activejob (= 6.1.3.2) activerecord (= 6.1.3.2) activesupport (= 6.1.3.2) marcel (~> 1.0.0) mini_mime (~> 1.0.2) activesupport (6.1.3.2) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.2) builder (3.2.4) chandler (0.9.0) netrc octokit (>= 2.2.0) concurrent-ruby (1.1.8) crass (1.0.6) erubi (1.10.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) globalid (0.4.2) activesupport (>= 4.2.0) has_scope (0.8.0) actionpack (>= 5.2) activesupport (>= 5.2) i18n (1.8.10) concurrent-ruby (~> 1.0) loofah (2.9.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.1) method_source (1.0.0) mini_mime (1.0.3) mini_portile2 (2.5.1) minitest (5.14.4) minitest-rg (5.2.0) minitest (~> 5.0) mocha (1.12.0) multipart-post (2.1.1) netrc (0.11.0) nio4r (2.5.7) nio4r (2.5.7-java) nokogiri (1.11.3) mini_portile2 (~> 2.5.0) racc (~> 1.4) nokogiri (1.11.3-java) racc (~> 1.4) octokit (4.18.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) parallel (1.20.1) parser (3.0.1.1) ast (~> 2.4.1) public_suffix (4.0.5) racc (1.5.2) racc (1.5.2-java) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) rails (6.1.3.2) actioncable (= 6.1.3.2) actionmailbox (= 6.1.3.2) actionmailer (= 6.1.3.2) actionpack (= 6.1.3.2) actiontext (= 6.1.3.2) actionview (= 6.1.3.2) activejob (= 6.1.3.2) activemodel (= 6.1.3.2) activerecord (= 6.1.3.2) activestorage (= 6.1.3.2) activesupport (= 6.1.3.2) bundler (>= 1.15.0) railties (= 6.1.3.2) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) railties (6.1.3.2) actionpack (= 6.1.3.2) activesupport (= 6.1.3.2) method_source rake (>= 0.8.7) thor (~> 1.0) rainbow (3.0.0) rake (13.0.3) regexp_parser (2.1.1) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.5) rubocop (1.14.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml rubocop-ast (>= 1.5.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.5.0) parser (>= 3.0.1.1) ruby-progressbar (1.11.0) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) thor (1.1.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) unicode-display_width (2.0.0) websocket-driver (0.7.3) websocket-extensions (>= 0.1.0) websocket-driver (0.7.3-java) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) zeitwerk (2.4.2) PLATFORMS java ruby DEPENDENCIES chandler inherited_resources! minitest-rg mocha rails (~> 6.1.3.a) rails-controller-testing rubocop BUNDLED WITH 2.2.17 inherited_resources-1.13.0/MIT-LICENSE000066400000000000000000000020441404526035200172760ustar00rootroot00000000000000Copyright (c) 2009-2017 José Valim Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. inherited_resources-1.13.0/README.md000066400000000000000000000527401404526035200171310ustar00rootroot00000000000000## Notice Inherited Resources is no longer actively maintained by the original author and has been transferred to the ActiveAdmin organization for maintenance. New feature requests are not encouraged. If you are not already using Inherited Resources we suggest instead using Rails' `respond_with` feature alongside the [responders gem](https://github.com/plataformatec/responders). ## Inherited Resources [![Version ][rubygems_badge]][rubygems] [![Github Actions ][actions_badge]][actions] [![Tidelift ][tidelift_badge]][tidelift] Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important. It makes your controllers more powerful and cleaner at the same time. In addition to making your controllers follow a pattern, it helps you to write better code by following fat models and skinny controllers convention. There are two screencasts available besides this README: * http://railscasts.com/episodes/230-inherited-resources * http://akitaonrails.com/2009/09/01/screencast-real-thin-restful-controllers-with-inherited-resources ## Installation You can let bundler install Inherited Resources by adding this line to your application's Gemfile: ```ruby gem 'inherited_resources' ``` And then execute: ```sh $ bundle install ``` Or install it yourself with: ```sh $ gem install inherited_resources ``` ## HasScope Since Inherited Resources 1.0, has_scope is not part of its core anymore but a gem dependency. Be sure to check the documentation to see how you can use it: - And it can be installed as: ```sh $ gem install has_scope ``` ## Responders Since Inherited Resources 1.0, responders are not part of its core anymore, but is set as Inherited Resources dependency and it's used by default by InheritedResources controllers. Be sure to check the documentation to see how it will change your application: - And it can be installed with: ```sh $ gem install responders ``` Using responders will set the flash message to :notice and :alert. You can change that through the following configuration value: ```ruby InheritedResources.flash_keys = [ :success, :failure ] ``` Notice the CollectionResponder won't work with InheritedResources, as InheritedResources hardcodes the redirect path based on the current scope (like belongs to, polymorphic associations, etc). ## Basic Usage To use Inherited Resources you just have to inherit (duh) it: ```ruby class ProjectsController < InheritedResources::Base end ``` And all actions are defined and working, check it! Your projects collection (in the index action) is still available in the instance variable `@projects` and your project resource (all other actions) is available as `@project`. The next step is to define which mime types this controller provides: ```ruby class ProjectsController < InheritedResources::Base respond_to :html, :xml, :json end ``` You can also specify them per action: ```ruby class ProjectsController < InheritedResources::Base respond_to :html, :xml, :json respond_to :js, :only => :create respond_to :iphone, :except => [ :edit, :update ] end ``` For each request, it first checks if the "controller/action.format" file is available (for example "projects/create.xml") and if it's not, it checks if the resource respond to :to_format (in this case, `:to_xml`). Otherwise returns 404. Another option is to specify which actions the controller will inherit from the `InheritedResources::Base`: ```ruby class ProjectsController < InheritedResources::Base actions :index, :show, :new, :create end ``` Or: ```ruby class ProjectsController < InheritedResources::Base actions :all, :except => [ :edit, :update, :destroy ] end ``` In your views, you will get the following helpers: ```ruby resource #=> @project collection #=> @projects resource_class #=> Project ``` As you might expect, collection (`@projects` instance variable) is only available on index actions. If for some reason you cannot inherit from `InheritedResources::Base`, you can call inherit_resources in your controller class scope: ```ruby class AccountsController < ApplicationController inherit_resources end ``` One reason to use the `inherit_resources` macro would be to ensure that your controller never responds with the html mime-type. `InheritedResources::Base` already responds to `:html`, and the `respond_to` macro is strictly additive. Therefore, if you want to create a controller that, for example, responds ONLY via `:js`, you will have to write it this way: ```ruby class AccountsController < ApplicationController respond_to :js inherit_resources end ``` ## Overwriting defaults Whenever you inherit from InheritedResources, several defaults are assumed. For example you can have an `AccountsController` for account management while the resource is a `User`: ```ruby class AccountsController < InheritedResources::Base defaults :resource_class => User, :collection_name => 'users', :instance_name => 'user' end ``` In the case above, in your views you will have `@users` and `@user` variables, but the routes used will still be `accounts_url` and `account_url`. If you plan also to change the routes, you can use `:route_collection_name` and `:route_instance_name`. Namespaced controllers work out of the box, but if you need to specify a different route prefix you can do the following: ```ruby class Administrators::PeopleController < InheritedResources::Base defaults :route_prefix => :admin end ``` Then your named routes will be: `admin_people_url`, `admin_person_url` instead of `administrators_people_url` and `administrators_person_url`. If you want to customize how resources are retrieved you can overwrite collection and resource methods. The first is called on index action and the second on all other actions. Let's suppose you want to add pagination to your projects collection: ```ruby class ProjectsController < InheritedResources::Base protected def collection get_collection_ivar || set_collection_ivar(end_of_association_chain.paginate(:page => params[:page])) end end ``` The `end_of_association_chain` returns your resource after nesting all associations and scopes (more about this below). InheritedResources also introduces another method called `begin_of_association_chain`. It's mostly used when you want to create resources based on the `@current_user` and you have urls like "account/projects". In such cases you have to do `@current_user.projects.find` or `@current_user.projects.build` in your actions. You can deal with it just by doing: ```ruby class ProjectsController < InheritedResources::Base protected def begin_of_association_chain @current_user end end ``` ## Overwriting actions Let's suppose that after destroying a project you want to redirect to your root url instead of redirecting to projects url. You just have to do: ```ruby class ProjectsController < InheritedResources::Base def destroy super do |format| format.html { redirect_to root_url } end end end ``` You are opening your action and giving the parent action a new behavior. On the other hand, I have to agree that calling super is not very readable. That's why all methods have aliases. So this is equivalent: ```ruby class ProjectsController < InheritedResources::Base def destroy destroy! do |format| format.html { redirect_to root_url } end end end ``` Since most of the time when you change a create, update or destroy action you do so because you want to change its redirect url, a shortcut is provided. So you can do: ```ruby class ProjectsController < InheritedResources::Base def destroy destroy! { root_url } end end ``` If you simply want to change the flash message for a particular action, you can pass the message to the parent action using the keys `:notice` and `:alert` (as you would with flash): ```ruby class ProjectsController < InheritedResources::Base def create create!(:notice => "Dude! Nice job creating that project.") end end ``` You can still pass the block to change the redirect, as mentioned above: ```ruby class ProjectsController < InheritedResources::Base def create create!(:notice => "Dude! Nice job creating that project.") { root_url } end end ``` Now let's suppose that before create a project you have to do something special but you don't want to create a before filter for it: ```ruby class ProjectsController < InheritedResources::Base def create @project = Project.new(params[:project]) @project.something_special! create! end end ``` Yes, it's that simple! The nice part is since you already set the instance variable `@project`, it will not build a project again. Same goes for updating the project: ```ruby class ProjectsController < InheritedResources::Base def update @project = Project.find(params[:id]) @project.something_special! update! end end ``` Before we finish this topic, we should talk about one more thing: "success/failure blocks". Let's suppose that when we update our project, in case of failure, we want to redirect to the project url instead of re-rendering the edit template. Our first attempt to do this would be: ```ruby class ProjectsController < InheritedResources::Base def update update! do |format| unless @project.errors.empty? # failure format.html { redirect_to project_url(@project) } end end end end ``` Looks too verbose, right? We can actually do: ```ruby class ProjectsController < InheritedResources::Base def update update! do |success, failure| failure.html { redirect_to project_url(@project) } end end end ``` Much better! So explaining everything: when you give a block which expects one argument it will be executed in both scenarios: success and failure. But if you give a block that expects two arguments, the first will be executed only in success scenarios and the second in failure scenarios. You keep everything clean and organized inside the same action. ## Smart redirects Although the syntax above is a nice shortcut, you won't need to do it frequently because (since version 1.2) Inherited Resources has smart redirects. Redirects in actions calculates depending on the existent controller methods. Redirects in create and update actions calculates in the following order: `resource_url`, `collection_url`, `parent_url` (which we are going to see later), and `root_url`. Redirect in destroy action calculate in following order `collection_url`, `parent_url`, `root_url`. Example: ```ruby class ButtonsController < InheritedResources::Base belongs_to :window actions :all, :except => [:show, :index] end ``` This controller redirect to parent window after all CUD actions. ## Success and failure scenarios on destroy The destroy action can also fail, this usually happens when you have a `before_destroy` callback in your model which returns false. However, in order to tell InheritedResources that it really failed, you need to add errors to your model. So your `before_destroy` callback on the model should be something like this: ```ruby def before_destroy if cant_be_destroyed? errors.add(:base, "not allowed") false end end ``` ## Belongs to Finally, our Projects are going to get some Tasks. Then you create a `TasksController` and do: ```ruby class TasksController < InheritedResources::Base belongs_to :project end ``` `belongs_to` accepts several options to be able to configure the association. For example, if you want urls like "/projects/:project_title/tasks", you can customize how InheritedResources find your projects: ```ruby class TasksController < InheritedResources::Base belongs_to :project, :finder => :find_by_title!, :param => :project_title end ``` It also accepts `:route_name`, `:parent_class` and `:instance_name` as options. Check the [lib/inherited_resources/class_methods.rb](https://github.com/activeadmin/inherited_resources/blob/master/lib/inherited_resources/class_methods.rb) for more. ## Nested belongs to Now, our Tasks get some Comments and you need to nest even deeper. Good practices says that you should never nest more than two resources, but sometimes you have to for security reasons. So this is an example of how you can do it: ```ruby class CommentsController < InheritedResources::Base nested_belongs_to :project, :task end ``` If you need to configure any of these belongs to, you can nest them using blocks: ```ruby class CommentsController < InheritedResources::Base belongs_to :project, :finder => :find_by_title!, :param => :project_title do belongs_to :task end end ``` Warning: calling several `belongs_to` is the same as nesting them: ```ruby class CommentsController < InheritedResources::Base belongs_to :project belongs_to :task end ``` In other words, the code above is the same as calling `nested_belongs_to`. ## Polymorphic belongs to We can go even further. Let's suppose our Projects can now have Files, Messages and Tasks, and they are all commentable. In this case, the best solution is to use polymorphism: ```ruby class CommentsController < InheritedResources::Base belongs_to :task, :file, :message, :polymorphic => true # polymorphic_belongs_to :task, :file, :message end ``` You can even use it with nested resources: ```ruby class CommentsController < InheritedResources::Base belongs_to :project do belongs_to :task, :file, :message, :polymorphic => true end end ``` The url in such cases can be: ``` /project/1/task/13/comments /project/1/file/11/comments /project/1/message/9/comments ``` When using polymorphic associations, you get some free helpers: ```ruby parent? #=> true parent_type #=> :task parent_class #=> Task parent #=> @task ``` Right now, Inherited Resources is limited and does not allow you to have two polymorphic associations nested. ## Optional belongs to Later you decide to create a view to show all comments, independent if they belong to a task, file or message. You can reuse your polymorphic controller just doing: ```ruby class CommentsController < InheritedResources::Base belongs_to :task, :file, :message, :optional => true # optional_belongs_to :task, :file, :message end ``` This will handle all those urls properly: ``` /comment/1 /tasks/2/comment/5 /files/10/comment/3 /messages/13/comment/11 ``` This is treated as a special type of polymorphic associations, thus all helpers are available. As you expect, when no parent is found, the helpers return: ```ruby parent? #=> false parent_type #=> nil parent_class #=> nil parent #=> nil ``` ## Singletons Now we are going to add manager to projects. We say that `Manager` is a singleton resource because a `Project` has just one manager. You should declare it as `has_one` (or resource) in your routes. To declare an resource of current controller as singleton, you just have to give the `:singleton` option in defaults. ```ruby class ManagersController < InheritedResources::Base defaults :singleton => true belongs_to :project # singleton_belongs_to :project end ``` So now you can use urls like "/projects/1/manager". In the case of nested resources (when some of the can be singletons) you can declare it separately ```ruby class WorkersController < InheritedResources::Base #defaults :singleton => true #if you have only single worker belongs_to :project belongs_to :manager, :singleton => true end ``` This is correspond urls like "/projects/1/manager/workers/1". It will deal with everything again and hide the action :index from you. ## Namespaced Controllers Namespaced controllers works out the box. ```ruby class Forum::PostsController < InheritedResources::Base end ``` Inherited Resources prioritizes the default resource class for the namespaced controller in this order: ``` Forum::Post ForumPost Post ``` ## URL Helpers When you use InheritedResources it creates some URL helpers. And they handle everything for you. :) ```ruby # /posts/1/comments resource_url # => /posts/1/comments/#{@comment.to_param} resource_url(comment) # => /posts/1/comments/#{comment.to_param} new_resource_url # => /posts/1/comments/new edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit edit_resource_url(comment) # => /posts/1/comments/#{comment.to_param}/edit collection_url # => /posts/1/comments parent_url # => /posts/1 # /projects/1/tasks resource_url # => /projects/1/tasks/#{@task.to_param} resource_url(task) # => /projects/1/tasks/#{task.to_param} new_resource_url # => /projects/1/tasks/new edit_resource_url # => /projects/1/tasks/#{@task.to_param}/edit edit_resource_url(task) # => /projects/1/tasks/#{task.to_param}/edit collection_url # => /projects/1/tasks parent_url # => /projects/1 # /users resource_url # => /users/#{@user.to_param} resource_url(user) # => /users/#{user.to_param} new_resource_url # => /users/new edit_resource_url # => /users/#{@user.to_param}/edit edit_resource_url(user) # => /users/#{user.to_param}/edit collection_url # => /users parent_url # => / ``` Those urls helpers also accepts a hash as options, just as in named routes. ```ruby # /projects/1/tasks collection_url(:page => 1, :limit => 10) #=> /projects/1/tasks?page=1&limit=10 ``` In polymorphic cases, you can also give the parent as parameter to `collection_url`. Another nice thing is that those urls are not guessed during runtime. They are all created when your application is loaded (except for polymorphic associations, that relies on Rails' `polymorphic_url`). ## Custom actions Since version 1.2, Inherited Resources allows you to define custom actions in controller: ```ruby class ButtonsController < InheritedResources::Base custom_actions :resource => :delete, :collection => :search end ``` This code creates delete and search actions in controller (they behaves like show and index actions accordingly). Also, it will produce `delete_resource_{path,url}` and `search_resources_{path,url}` url helpers. ## What about views? Sometimes just DRYing up the controllers is not enough. If you need to DRY up your views, check this Wiki page: https://github.com/activeadmin/inherited_resources/wiki/Views-Inheritance Notice that Rails 3.1 ships with view inheritance built-in. ## Some DSL For those DSL lovers, InheritedResources won't leave you alone. You can overwrite your success/failure blocks straight from your class binding. For it, you just need to add a DSL module to your application controller: ```ruby class ApplicationController < ActionController::Base include InheritedResources::DSL end ``` And then you can rewrite the last example as: ```ruby class ProjectsController < InheritedResources::Base update! do |success, failure| failure.html { redirect_to project_url(@project) } end end ``` ## Strong Parameters If your controller defines a method named `permitted_params`, InheritedResources will call it where it would normally call params. This allows for easy integration with the strong_parameters gem: ```ruby def permitted_params params.permit(:widget => [:permitted_field, :other_permitted_field]) end ``` Remember that if your field is sent by client to server as an array, you have to write `:permitted_field => []`, not just `:permitted_field`. Note that this doesn't work if you use strong_parameters' require method instead of permit, because whereas permit returns the entire sanitized parameter hash, require returns only the sanitized params below the parameter you required. If you need `params.require` you can do it like this: ```ruby def permitted_params {:widget => params.fetch(:widget, {}).permit(:permitted_field, :other_permitted_field)} end ``` Or better yet just override `#build_resource_params` directly: ```ruby def build_resource_params [params.fetch(:widget, {}).permit(:permitted_field, :other_permitted_field)] end ``` Instead you can stick to a standard Rails 4 notation (as rails scaffold generates) and write: ```ruby def widget_params params.require(:widget).permit(:permitted_field, :other_permitted_field) end ``` In such case you should remove #permitted_params method because it has greater priority. ## Funding If you want to support us financially, you can [help fund the project through a Tidelift subscription][tidelift]. By buying a Tidelift subscription you make sure your whole dependency stack is properly maintained, while also getting a comprehensive view of outdated dependencies, new releases, security alerts, and licensing compatibility issues. ## Bugs and Feedback If you discover any bugs, please describe it in the issues tracker, including Rails and InheritedResources versions. Questions are better handled on StackOverflow. MIT License. Copyright (c) 2009-2017 José Valim. ## Security contact information Please use the Tidelift security contact to [report a security vulnerability][Tidelift security contact]. Tidelift will coordinate the fix and disclosure. [rubygems_badge]: http://img.shields.io/gem/v/inherited_resources.svg [rubygems]: https://rubygems.org/gems/inherited_resources [actions_badge]: https://github.com/activeadmin/inherited_resources/workflows/ci/badge.svg [actions]: https://github.com/activeadmin/inherited_resources/actions [tidelift_badge]: https://tidelift.com/badges/github/activeadmin/inherited_resources [tidelift]: https://tidelift.com/subscription/pkg/rubygems-inherited-resources?utm_source=rubygems-inherited-resources&utm_medium=referral&utm_campaign=readme [Tidelift security contact]: https://tidelift.com/security inherited_resources-1.13.0/Rakefile000066400000000000000000000013101404526035200173020ustar00rootroot00000000000000require 'bundler/gem_tasks' require 'rake/testtask' require 'rdoc/task' import 'tasks/gemfiles.rake' import 'tasks/release.rake' desc 'Run tests for InheritedResources.' Rake::TestTask.new(:test) do |t| t.pattern = "test/**/*_test.rb" t.libs << "test" t.libs << "lib" t.verbose = true end desc 'Generate documentation for InheritedResources.' Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'InheritedResources' rdoc.options << '--line-numbers' << '--inline-source' rdoc.rdoc_files.include('README.rdoc') rdoc.rdoc_files.include('MIT-LICENSE') rdoc.rdoc_files.include('lib/**/*.rb') end task :rubocop do sh('bin/rubocop') end task default: [:test, :rubocop] inherited_resources-1.13.0/app/000077500000000000000000000000001404526035200164225ustar00rootroot00000000000000inherited_resources-1.13.0/app/controllers/000077500000000000000000000000001404526035200207705ustar00rootroot00000000000000inherited_resources-1.13.0/app/controllers/inherited_resources/000077500000000000000000000000001404526035200250355ustar00rootroot00000000000000inherited_resources-1.13.0/app/controllers/inherited_resources/base.rb000066400000000000000000000034761404526035200263060ustar00rootroot00000000000000module InheritedResources # = Base # # This is the base class that holds all actions. If you see the code for each # action, they are quite similar to Rails default scaffold. # # To change your base behavior, you can overwrite your actions and call super, # call default class method, call <actions class method # or overwrite some helpers in the base_helpers.rb file. # class Base < ::ApplicationController # Overwrite inherit_resources to add specific InheritedResources behavior. def self.inherit_resources(base) base.class_eval do include InheritedResources::Actions include InheritedResources::BaseHelpers extend InheritedResources::ClassMethods extend InheritedResources::UrlHelpers # Add at least :html mime type respond_to :html if self.mimes_for_respond_to.empty? self.responder = InheritedResources::Responder helper_method :resource, :collection, :resource_class, :association_chain, :resource_instance_name, :resource_collection_name, :resource_url, :resource_path, :collection_url, :collection_path, :new_resource_url, :new_resource_path, :edit_resource_url, :edit_resource_path, :parent_url, :parent_path, :smart_resource_url, :smart_collection_url self.class_attribute :resource_class, instance_writer: false unless self.respond_to? :resource_class self.class_attribute :parents_symbols, :resources_configuration, instance_writer: false protected :resource_class, :parents_symbols, :resources_configuration, :resource_class?, :parents_symbols?, :resources_configuration? end end inherit_resources(self) end end inherited_resources-1.13.0/bin/000077500000000000000000000000001404526035200164125ustar00rootroot00000000000000inherited_resources-1.13.0/bin/chandler000077500000000000000000000014371404526035200201250ustar00rootroot00000000000000#!/usr/bin/env ruby # frozen_string_literal: true # # This file was generated by Bundler. # # The application 'chandler' is installed as part of a gem, and # this file is here to facilitate running it. # require "pathname" ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath) bundle_binstub = File.expand_path("../bundle", __FILE__) if File.file?(bundle_binstub) if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ load(bundle_binstub) else abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") end end require "rubygems" require "bundler/setup" load Gem.bin_path("chandler", "chandler") inherited_resources-1.13.0/bin/rake000077500000000000000000000014231404526035200172620ustar00rootroot00000000000000#!/usr/bin/env ruby # frozen_string_literal: true # # This file was generated by Bundler. # # The application 'rake' is installed as part of a gem, and # this file is here to facilitate running it. # require "pathname" ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath) bundle_binstub = File.expand_path("../bundle", __FILE__) if File.file?(bundle_binstub) if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ load(bundle_binstub) else abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") end end require "rubygems" require "bundler/setup" load Gem.bin_path("rake", "rake") inherited_resources-1.13.0/bin/rubocop000077500000000000000000000002651404526035200200140ustar00rootroot00000000000000#!/usr/bin/env ruby # frozen_string_literal: true ENV["BUNDLE_GEMFILE"] = File.expand_path("../Gemfile", __dir__) require "bundler/setup" load Gem.bin_path("rubocop", "rubocop") inherited_resources-1.13.0/inherited_resources.gemspec000066400000000000000000000022721404526035200232570ustar00rootroot00000000000000lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "inherited_resources/version" Gem::Specification.new do |s| s.name = "inherited_resources" s.version = InheritedResources::VERSION.dup s.platform = Gem::Platform::RUBY s.summary = "Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important." s.homepage = "https://github.com/activeadmin/inherited_resources" s.description = <<~MSG Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important. It makes your controllers more powerful and cleaner at the same time. MSG s.authors = ['José Valim', 'Rafael Mendonça França'] s.license = "MIT" s.files = Dir["app/**/*", "lib/**/*", "README.md", "MIT-LICENSE"] s.require_paths = ["lib"] s.required_ruby_version = '>= 2.5' s.add_dependency("responders", ">= 2", "< 4") s.add_dependency("actionpack", ">= 5.2", "< 6.2") s.add_dependency("railties", ">= 5.2", "< 6.2") s.add_dependency("has_scope", "~> 0.6") end inherited_resources-1.13.0/lib/000077500000000000000000000000001404526035200164105ustar00rootroot00000000000000inherited_resources-1.13.0/lib/generators/000077500000000000000000000000001404526035200205615ustar00rootroot00000000000000inherited_resources-1.13.0/lib/generators/rails/000077500000000000000000000000001404526035200216735ustar00rootroot00000000000000inherited_resources-1.13.0/lib/generators/rails/USAGE000066400000000000000000000007401404526035200224630ustar00rootroot00000000000000Description: Stubs out a scaffolded controller and its views using InheritedResources. Pass the model name, either CamelCased or under_scored. The controller name is retrieved as a pluralized version of the model name. To create a controller within a module, specify the model name as a path like 'parent_module/controller_name'. This generates a controller class in app/controllers and invokes helper, template engine and test framework generators. inherited_resources-1.13.0/lib/generators/rails/inherited_resources_controller_generator.rb000066400000000000000000000005111404526035200325730ustar00rootroot00000000000000require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' module Rails module Generators class InheritedResourcesControllerGenerator < ScaffoldControllerGenerator def self.source_root @source_root ||= File.expand_path("templates", File.dirname(__FILE__)) end end end end inherited_resources-1.13.0/lib/generators/rails/templates/000077500000000000000000000000001404526035200236715ustar00rootroot00000000000000inherited_resources-1.13.0/lib/generators/rails/templates/controller.rb.tt000066400000000000000000000005001404526035200270220ustar00rootroot00000000000000class <%= controller_class_name %>Controller < InheritedResources::Base <% if options[:singleton] -%> defaults :singleton => true <% end -%> private def <%= singular_name %>_params params.require(:<%= singular_name %>).permit(<%= attributes_names.map{ |a_name| ":#{a_name}" }.join(", ") %>) end end inherited_resources-1.13.0/lib/inherited_resources.rb000066400000000000000000000032461404526035200230070ustar00rootroot00000000000000# This is here because responders don't require it. require 'rails/engine' require 'responders' require 'inherited_resources/engine' require 'inherited_resources/blank_slate' require 'inherited_resources/responder' module InheritedResources ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?(:ACTIONS) autoload :Actions, 'inherited_resources/actions' autoload :BaseHelpers, 'inherited_resources/base_helpers' autoload :ShallowHelpers, 'inherited_resources/shallow_helpers' autoload :BelongsToHelpers, 'inherited_resources/belongs_to_helpers' autoload :ClassMethods, 'inherited_resources/class_methods' autoload :DSL, 'inherited_resources/dsl' autoload :PolymorphicHelpers, 'inherited_resources/polymorphic_helpers' autoload :SingletonHelpers, 'inherited_resources/singleton_helpers' autoload :UrlHelpers, 'inherited_resources/url_helpers' autoload :VERSION, 'inherited_resources/version' # Change the flash keys used by FlashResponder. def self.flash_keys=(array) Responders::FlashResponder.flash_keys = array end end ActiveSupport.on_load(:action_controller) do # We can remove this check and change to `on_load(:action_controller_base)` in Rails 5.2. if self == ActionController::Base # If you cannot inherit from InheritedResources::Base you can call # inherit_resources in your controller to have all the required modules and # funcionality included. def self.inherit_resources InheritedResources::Base.inherit_resources(self) initialize_resources_class_accessors! create_resources_url_helpers! end end end inherited_resources-1.13.0/lib/inherited_resources/000077500000000000000000000000001404526035200224555ustar00rootroot00000000000000inherited_resources-1.13.0/lib/inherited_resources/actions.rb000066400000000000000000000031431404526035200244430ustar00rootroot00000000000000module InheritedResources # Holds all default actions for InheritedResouces. module Actions # GET /resources def index(options={}, &block) respond_with(*with_chain(collection), options, &block) end alias :index! :index # GET /resources/1 def show(options={}, &block) respond_with(*with_chain(resource), options, &block) end alias :show! :show # GET /resources/new def new(options={}, &block) respond_with(*with_chain(build_resource), options, &block) end alias :new! :new # GET /resources/1/edit def edit(options={}, &block) respond_with(*with_chain(resource), options, &block) end alias :edit! :edit # POST /resources def create(options={}, &block) object = build_resource if create_resource(object) options[:location] ||= smart_resource_url end respond_with_dual_blocks(object, options, &block) end alias :create! :create # PUT /resources/1 def update(options={}, &block) object = resource if update_resource(object, resource_params) options[:location] ||= smart_resource_url end respond_with_dual_blocks(object, options, &block) end alias :update! :update # DELETE /resources/1 def destroy(options={}, &block) object = resource options[:location] ||= smart_collection_url destroy_resource(object) respond_with_dual_blocks(object, options, &block) end alias :destroy! :destroy # Make aliases protected protected :index!, :show!, :new!, :create!, :edit!, :update!, :destroy! end end inherited_resources-1.13.0/lib/inherited_resources/base_helpers.rb000066400000000000000000000313131404526035200254370ustar00rootroot00000000000000# Whenever base is required load the dumb responder since it's used inside actions. require 'inherited_resources/blank_slate' module InheritedResources # Base helpers for InheritedResource work. Some methods here can be overwritten # and you will need to do that to customize your controllers from time to time. # module BaseHelpers protected # This is how the collection is loaded. # # You might want to overwrite this method if you want to add pagination # for example. When you do that, don't forget to cache the result in an # instance_variable: # # def collection # @projects ||= end_of_association_chain.paginate(params[:page]).all # end # def collection get_collection_ivar || begin c = end_of_association_chain set_collection_ivar(c.respond_to?(:scoped) ? c.scoped : c.all) end end # This is how the resource is loaded. # # You might want to overwrite this method when you are using permalink. # When you do that, don't forget to cache the result in an # instance_variable: # # def resource # @project ||= end_of_association_chain.find_by_permalink!(params[:id]) # end # # You also might want to add the exclamation mark at the end of the method # because it will raise a 404 if nothing can be found. Otherwise it will # probably render a 500 error message. # def resource get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_find, params[:id])) end # This method is responsible for building the object on :new and :create # methods. If you overwrite it, don't forget to cache the result in an # instance variable. # def build_resource get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_build, *resource_params)) end # Responsible for saving the resource on :create method. Overwriting this # allow you to control the way resource is saved. Let's say you have a # PassworsController who is responsible for finding an user by email and # sent password instructions for him. Instead of overwriting the entire # :create method, you could do something: # # def create_resource(object) # object.send_instructions_by_email # end # def create_resource(object) object.save end # Responsible for updating the resource in :update method. This allow you # to handle how the resource is going to be updated, let's say in a different # way than the usual :update: # # def update_resource(object, attributes) # object.reset_password!(attributes) # end # def update_resource(object, attributes) object.update(*attributes) end # Handle the :destroy method for the resource. Overwrite it to call your # own method for destroying the resource, as: # # def destroy_resource(object) # object.cancel # end # def destroy_resource(object) object.destroy end # This class allows you to set a instance variable to begin your # association chain. For example, usually your projects belongs to users # and that means that they belong to the current logged in user. So you # could do this: # # def begin_of_association_chain # @current_user # end # # So every time we instantiate a project, we will do: # # @current_user.projects.build(params[:project]) # @current_user.projects.find(params[:id]) # # The variable set in begin_of_association_chain is not sent when building # urls, so this is never going to happen when calling resource_url: # # project_url(@current_user, @project) # # If the user actually scopes the url, you should use belongs_to method # and declare that projects belong to user. # def begin_of_association_chain nil end # Returns if the controller has a parent. When only base helpers are loaded, # it's always false and should not be overwritten. # def parent? false end # Returns the association chain, with all parents (does not include the # current resource). # def association_chain @association_chain ||= symbols_for_association_chain.inject([begin_of_association_chain]) do |chain, symbol| chain << evaluate_parent(symbol, resources_configuration[symbol], chain.last) end.compact.freeze end # rubocop:disable Layout/CommentIndentation # See https://github.com/rubocop-hq/rubocop/issues/6450 # # Overwrite this method to provide other interpolation options when # the flash message is going to be set. # # def flash_interpolation_options # { } # end # # rubocop:enable Layout/CommentIndentation private # Adds the given object to association chain. def with_chain(object) association_chain + [ object ] end # Fast accessor to resource_collection_name # def resource_collection_name #:nodoc: self.resources_configuration[:self][:collection_name] end # Fast accessor to resource_instance_name # def resource_instance_name #:nodoc: self.resources_configuration[:self][:instance_name] end def resource_request_name self.resources_configuration[:self][:request_name] end # This methods gets your begin_of_association_chain, join it with your # parents chain and returns the scoped association. def end_of_association_chain #:nodoc: if chain = association_chain.last if method_for_association_chain apply_scopes_if_available(chain.send(method_for_association_chain)) else # This only happens when we specify begin_of_association_chain in # a singleton controller without parents. In this case, the chain # is exactly the begin_of_association_chain which is already an # instance and then not scopable. chain end else apply_scopes_if_available(resource_class) end end # Returns the appropriated method to build the resource. # def method_for_build #:nodoc: (begin_of_association_chain || parent?) ? method_for_association_build : :new end # Returns the name of the method used for building the resource in cases # where we have a parent. This is overwritten in singleton scenarios. # def method_for_association_build :build end # Returns the name of the method to be called, before returning the end # of the association chain. This is overwritten by singleton cases # where no method for association chain is called. # def method_for_association_chain #:nodoc: resource_collection_name end # Returns finder method for instantiate resource by params[:id] def method_for_find resources_configuration[:self][:finder] || :find end # Get resource ivar based on the current resource controller. # def get_resource_ivar #:nodoc: if instance_variable_defined?(:"@#{resource_instance_name}") instance_variable_get("@#{resource_instance_name}") else nil end end # Set resource ivar based on the current resource controller. # def set_resource_ivar(resource) #:nodoc: instance_variable_set("@#{resource_instance_name}", resource) end # Get collection ivar based on the current resource controller. # def get_collection_ivar #:nodoc: if instance_variable_defined?(:"@#{resource_collection_name}") instance_variable_get("@#{resource_collection_name}") else nil end end # Set collection ivar based on the current resource controller. # def set_collection_ivar(collection) #:nodoc: instance_variable_set("@#{resource_collection_name}", collection) end # Used to allow to specify success and failure within just one block: # # def create # create! do |success, failure| # failure.html { redirect_to root_url } # end # end # # It also calculates the response url in case a block without arity is # given and returns it. Otherwise returns nil. # def respond_with_dual_blocks(object, options, &block) #:nodoc: args = (with_chain(object) << options) case block.try(:arity) when 2 respond_with(*args) do |responder| blank_slate = InheritedResources::BlankSlate.new if object.errors.empty? block.call(responder, blank_slate) else block.call(blank_slate, responder) end end when 1 respond_with(*args, &block) else options[:location] = block.call if block respond_with(*args) end end # Hook to apply scopes. By default returns only the target_object given. # It's extend by HasScopeHelpers. # def apply_scopes_if_available(target_object) #:nodoc: respond_to?(:apply_scopes, true) ? apply_scopes(target_object) : target_object end # Symbols chain in base helpers return nothing. This is later overwritten # by belongs_to and can be complex in polymorphic cases. # def symbols_for_association_chain #:nodoc: [] end # URL to redirect to when redirect implies resource url. def smart_resource_url url = nil if respond_to? :show url = resource_url rescue nil end url ||= smart_collection_url end # URL to redirect to when redirect implies collection url. def smart_collection_url url = nil if respond_to? :index url ||= collection_url rescue nil end if respond_to? :parent, true url ||= parent_url rescue nil end url ||= root_url rescue nil end # memoize the extraction of attributes from params def resource_params @resource_params ||= build_resource_params end def resource_params_method_name "#{resource_instance_name}_params" end # Returns hash of sanitized params in a form like # `{:project => {:project_attribute => 'value'}}` # # This method makes use of `project_params` (or `smth_else_params`) which # is a default Rails controller method for strong parameters definition. # # `permitted_params` is usually fired by method :new, :create, :update # actions. Action :new usually has no parameters so strong parameters # `require` directive raises a +ActionController::ParameterMissing+ # exception. `#permitted_params` rescues such exceptions in :new and # returns an empty hash of parameters (which is reasonable default). # If for any reasons you need something more specific, you can redefine # this method in a way previous `inherited_resources` versions did: # # # Unnecessary redefinition # def permitted_params # params.permit(:project => [:project_attribute]) # end # def permitted_params return nil unless respond_to?(resource_params_method_name, true) {resource_request_name => send(resource_params_method_name)} rescue ActionController::ParameterMissing # typically :new action if params[:action].to_s == 'new' {resource_request_name => {}} else raise end end # extract attributes from params def build_resource_params parameters = permitted_params || params rparams = [parameters[resource_request_name] || parameters[resource_instance_name] || {}] if without_protection_given? rparams << without_protection else rparams << as_role if role_given? end rparams end # checking if role given def role_given? self.resources_configuration[:self][:role].present? end # getting role for mass-asignment def as_role { as: self.resources_configuration[:self][:role] } end def without_protection_given? self.resources_configuration[:self][:without_protection].present? end def without_protection { without_protection: self.resources_configuration[:self][:without_protection] } end end end inherited_resources-1.13.0/lib/inherited_resources/belongs_to_helpers.rb000066400000000000000000000065411404526035200266650ustar00rootroot00000000000000module InheritedResources # = belongs_to # # Let's suppose that we have some tasks that belongs to projects. To specify # this assoication in your controllers, just do: # # class TasksController < InheritedResources::Base # belongs_to :project # end # # belongs_to accepts several options to be able to configure the association. # For example, if you want urls like /projects/:project_title/tasks, you # can customize how InheritedResources find your projects: # # class TasksController < InheritedResources::Base # belongs_to :project, :finder => :find_by_title!, :param => :project_title # end # # It also accepts :route_name, :parent_class and :instance_name as options. # Check the lib/inherited_resources/class_methods.rb for more. # # = nested_belongs_to # # Now, our Tasks get some Comments and you need to nest even deeper. Good # practices says that you should never nest more than two resources, but sometimes # you have to for security reasons. So this is an example of how you can do it: # # class CommentsController < InheritedResources::Base # nested_belongs_to :project, :task # end # # If you need to configure any of these belongs to, you can nested them using blocks: # # class CommentsController < InheritedResources::Base # belongs_to :project, :finder => :find_by_title!, :param => :project_title do # belongs_to :task # end # end # # Warning: calling several belongs_to is the same as nesting them: # # class CommentsController < InheritedResources::Base # belongs_to :project # belongs_to :task # end # # In other words, the code above is the same as calling nested_belongs_to. # module BelongsToHelpers protected # Parent is always true when belongs_to is called. # def parent? true end def parent @parent ||= association_chain[-1] end def parent_type parent.class.name.underscore.to_sym end private # Evaluate the parent given. This is used to nest parents in the # association chain. # def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc: get_parent_ivar(parent_config[:instance_name]) || set_parent_instance(parent_config, chain) end def get_parent_ivar(instance_name) #:nodoc: instance_variable_defined?(:"@#{instance_name}") && instance_variable_get("@#{instance_name}") end def set_parent_instance(parent_config, chain) #:nodoc: if parent_config[:singleton] parent = if chain chain.send(parent_config[:instance_name]) else nil end else parent = if chain chain.send(parent_config[:collection_name]) else parent_config[:parent_class] end parent = parent.send(parent_config[:finder], params[parent_config[:param]]) end instance_variable_set("@#{parent_config[:instance_name]}", parent) end # Maps parents_symbols to build association chain. In this case, it # simply return the parent_symbols, however on polymorphic belongs to, # it has some customization. # def symbols_for_association_chain #:nodoc: parents_symbols end end end inherited_resources-1.13.0/lib/inherited_resources/blank_slate.rb000066400000000000000000000004131404526035200252570ustar00rootroot00000000000000module InheritedResources # An object from BlankSlate simply discards all messages sent to it. class BlankSlate instance_methods.each do |m| undef_method m unless m =~ /^(__|object_id)/ end def method_missing(*args) nil end end end inherited_resources-1.13.0/lib/inherited_resources/class_methods.rb000066400000000000000000000402151404526035200256340ustar00rootroot00000000000000module InheritedResources module ClassMethods protected # Used to overwrite the default assumptions InheritedResources do. Whenever # this method is called, it should be on the top of your controller, since # almost other methods depends on the values given to <>defaults. # # == Options # # * :resource_class - The resource class which by default is guessed # by the controller name. Defaults to Project in # ProjectsController. # # * :collection_name - The name of the collection instance variable which # is set on the index action. Defaults to :projects in # ProjectsController. # # * :instance_name - The name of the singular instance variable which # is set on all actions besides index action. Defaults to # :project in ProjectsController. # # * :route_collection_name - The name of the collection route. Defaults to :collection_name. # # * :route_instance_name - The name of the singular route. Defaults to :instance_name. # # * :route_prefix - The route prefix which is automically set in namespaced # controllers. Default to :admin on Admin::ProjectsController. # # * :singleton - Tells if this controller is singleton or not. # # * :finder - Specifies which method should be called to instantiate the resource. # # defaults :finder => :find_by_slug # def defaults(options) raise ArgumentError, 'Class method :defaults expects a hash of options.' unless options.is_a? Hash options.symbolize_keys! options.assert_valid_keys(:resource_class, :collection_name, :instance_name, :class_name, :route_prefix, :route_collection_name, :route_instance_name, :singleton, :finder) self.resource_class = options[:resource_class] if options.key?(:resource_class) self.resource_class = options[:class_name].constantize if options.key?(:class_name) acts_as_singleton! if options.delete(:singleton) config = self.resources_configuration[:self] if options.key?(:resource_class) or options.key?(:class_name) config[:request_name] = begin request_name = self.resource_class request_name = request_name.model_name.param_key if request_name.respond_to?(:model_name) request_name.to_s.underscore.gsub('/', '_') end options.delete(:resource_class) and options.delete(:class_name) end options.each do |key, value| config[key] = value&.to_sym end create_resources_url_helpers! end # Defines wich actions will be inherited from the inherited controller. # Syntax is borrowed from resource_controller. # # actions :index, :show, :edit # actions :all, :except => :index # def actions(*actions_to_keep) raise ArgumentError, 'Wrong number of arguments. You have to provide which actions you want to keep.' if actions_to_keep.empty? options = actions_to_keep.extract_options! actions_to_remove = Array(options[:except]) actions_to_remove += ACTIONS - actions_to_keep.map { |a| a.to_sym } unless actions_to_keep.first == :all actions_to_remove.map! { |a| a.to_sym }.uniq! (instance_methods.map { |m| m.to_sym } & actions_to_remove).each do |action| undef_method action, "#{action}!" end end # Defines that this controller belongs to another resource. # # belongs_to :projects # # == Options # # * :parent_class - Allows you to specify what is the parent class. # # belongs_to :project, :parent_class => AdminProject # # * :class_name - Also allows you to specify the parent class, but you should # give a string. Added for ActiveRecord belongs to compatibility. # # * :instance_name - The instance variable name. By default is the name of the association. # # belongs_to :project, :instance_name => :my_project # # * :finder - Specifies which method should be called to instantiate the parent. # # belongs_to :project, :finder => :find_by_title! # # This will make your projects be instantiated as: # # Project.find_by_title!(params[:project_id]) # # Instead of: # # Project.find(params[:project_id]) # # * :param - Allows you to specify params key to retrieve the id. # Default is :association_id, which in this case is :project_id. # # * :route_name - Allows you to specify what is the route name in your url # helper. By default is association name. # # * :collection_name - Tell how to retrieve the next collection. Let's # suppose you have Tasks which belongs to Projects # which belongs to companies. This will do somewhere # down the road: # # @company.projects # # But if you want to retrieve instead: # # @company.admin_projects # # You supply the collection name. # # * :polymorphic - Tell the association is polymorphic. # # * :singleton - Tell it's a singleton association. # # * :optional - Tell the association is optional (it's a special # type of polymorphic association) # def belongs_to(*symbols, &block) options = symbols.extract_options! options.symbolize_keys! options.assert_valid_keys(:class_name, :parent_class, :instance_name, :param, :finder, :route_name, :collection_name, :singleton, :polymorphic, :optional, :shallow) optional = options.delete(:optional) shallow = options.delete(:shallow) polymorphic = options.delete(:polymorphic) finder = options.delete(:finder) if self.parents_symbols.empty? include BelongsToHelpers helper_method :parent, :parent? end acts_as_polymorphic! if polymorphic || optional acts_as_shallow! if shallow raise ArgumentError, 'You have to give me at least one association name.' if symbols.empty? raise ArgumentError, "You cannot define multiple associations with options: #{options.keys.inspect} to belongs to." unless symbols.size == 1 || options.empty? symbols.each do |symbol| symbol = symbol.to_sym if polymorphic || optional self.parents_symbols << :polymorphic unless self.parents_symbols.include?(:polymorphic) self.resources_configuration[:polymorphic][:symbols] << symbol self.resources_configuration[:polymorphic][:optional] ||= optional else self.parents_symbols << symbol end self.resources_configuration[:self][:shallow] = true if shallow config = self.resources_configuration[symbol] = {} class_name = '' config[:parent_class] = options.delete(:parent_class) || begin class_name = if options[:class_name] options.delete(:class_name) else namespace = self.name.deconstantize model_name = symbol.to_s.pluralize.classify klass = model_name while namespace != '' new_klass = "#{namespace}::#{model_name}" if new_klass.safe_constantize klass = new_klass break else namespace = namespace.deconstantize end end klass = model_name if klass.start_with?('::') klass end class_name.constantize rescue NameError => e raise unless e.message.include?(class_name) nil end config[:singleton] = options.delete(:singleton) || false config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym config[:instance_name] = options.delete(:instance_name) || symbol config[:param] = options.delete(:param) || :"#{symbol}_id" config[:route_name] = options.delete(:route_name) || symbol config[:finder] = finder || :find end if block_given? class_eval(&block) else create_resources_url_helpers! end end alias :nested_belongs_to :belongs_to # A quick method to declare polymorphic belongs to. # def polymorphic_belongs_to(*symbols, &block) options = symbols.extract_options! options.merge!(polymorphic: true) belongs_to(*symbols, options, &block) end # A quick method to declare singleton belongs to. # def singleton_belongs_to(*symbols, &block) options = symbols.extract_options! options.merge!(singleton: true) belongs_to(*symbols, options, &block) end # A quick method to declare optional belongs to. # def optional_belongs_to(*symbols, &block) options = symbols.extract_options! options.merge!(optional: true) belongs_to(*symbols, options, &block) end # Defines custom restful actions by resource or collection basis. # # custom_actions :resource => [:delete, :transit], :collection => :search # # == Options # # * :resource - Allows you to specify resource actions. # custom_actions :resource => :delete # This macro creates 'delete' method in controller and defines # delete_resource_{path,url} helpers. The body of generated 'delete' # method is same as 'show' method. So you can override it if need # # * :collection - Allows you to specify collection actions. # custom_actions :collection => :search # This macro creates 'search' method in controller and defines # search_resources_{path,url} helpers. The body of generated 'search' # method is same as 'index' method. So you can override it if need # def custom_actions(options) self.resources_configuration[:self][:custom_actions] = options options.each do | resource_or_collection, actions | [*actions].each do | action | create_custom_action(resource_or_collection, action) end end create_resources_url_helpers! [*options[:resource]].each do | action | helper_method "#{action}_resource_path", "#{action}_resource_url" end [*options[:collection]].each do | action | helper_method "#{action}_resources_path", "#{action}_resources_url" end end # Defines the role to use when creating or updating resource. # Makes sense when using rails 3.1 mass assignment conventions def with_role(role) self.resources_configuration[:self][:role] = role.try(:to_sym) end def without_protection(flag) self.resources_configuration[:self][:without_protection] = flag end private def acts_as_singleton! #:nodoc: unless self.resources_configuration[:self][:singleton] self.resources_configuration[:self][:singleton] = true include SingletonHelpers actions :all, except: :index end end def acts_as_polymorphic! #:nodoc: unless self.parents_symbols.include?(:polymorphic) include PolymorphicHelpers helper_method :parent_type, :parent_class end end def acts_as_shallow! #:nodoc: include BelongsToHelpers include ShallowHelpers end # Initialize resources class accessors and set their default values. # def initialize_resources_class_accessors! #:nodoc: # First priority is the namespaced model, e.g. User::Group self.resource_class ||= begin namespaced_class = self.name.sub(/Controller$/, '').singularize namespaced_class.constantize rescue NameError nil end # Second priority is the top namespace model, e.g. EngineName::Article for EngineName::Admin::ArticlesController self.resource_class ||= begin namespaced_classes = self.name.sub(/Controller$/, '').split('::') namespaced_class = [namespaced_classes.first, namespaced_classes.last].join('::').singularize namespaced_class.constantize rescue NameError nil end # Third priority the camelcased c, i.e. UserGroup self.resource_class ||= begin camelcased_class = self.name.sub(/Controller$/, '').gsub('::', '').singularize camelcased_class.constantize rescue NameError nil end # Otherwise use the Group class, or fail self.resource_class ||= begin class_name = self.controller_name.classify class_name.constantize rescue NameError => e raise unless e.message.include?(class_name) nil end self.parents_symbols = self.parents_symbols.try(:dup) || [] # Initialize resources configuration hash self.resources_configuration = self.resources_configuration.try(:dup) || {} self.resources_configuration.each do |key, value| next unless value.is_a?(Hash) || value.is_a?(Array) self.resources_configuration[key] = value.dup end config = (self.resources_configuration[:self] ||= {}) config[:collection_name] = self.controller_name.to_sym config[:instance_name] = self.controller_name.singularize.to_sym config[:route_collection_name] = config[:collection_name] config[:route_instance_name] = config[:instance_name] # Deal with namespaced controllers namespaces = self.controller_path.split('/')[0..-2] # Remove namespace if its a mountable engine namespaces.delete_if do |namespace| begin "#{namespace}/engine".camelize.constantize.isolated? rescue StandardError, LoadError false end end config[:route_prefix] = namespaces.join('_').to_sym unless namespaces.empty? # Deal with default request parameters in namespaced controllers, e.g. # Forum::Thread#create will properly pick up the request parameter # which will be forum_thread, and not thread # Additionally make this work orthogonally with instance_name config[:request_name] = self.resource_class.to_s.underscore.gsub('/', '_') # Initialize polymorphic, singleton, scopes and belongs_to parameters polymorphic = self.resources_configuration[:polymorphic] || { symbols: [], optional: false } polymorphic[:symbols] = polymorphic[:symbols].dup self.resources_configuration[:polymorphic] = polymorphic end def create_custom_action(resource_or_collection, action) class_eval <<-CUSTOM_ACTION, __FILE__, __LINE__ def #{action}(options={}, &block) respond_with(*with_chain(#{resource_or_collection}), options, &block) end alias :#{action}! :#{action} protected :#{action}! CUSTOM_ACTION end # Hook called on inheritance. # def inherited(base) #:nodoc: super(base) base.send :initialize_resources_class_accessors! base.send :create_resources_url_helpers! end end end inherited_resources-1.13.0/lib/inherited_resources/dsl.rb000066400000000000000000000012651404526035200235700ustar00rootroot00000000000000module InheritedResources # Allows controllers to write actions using a class method DSL. # # class MyController < InheritedResources::Base # create! do |success, failure| # success.html { render :text => "It works!" } # end # end # module DSL def self.included(base) ACTIONS.each do |action| base.class_eval <<-WRITTER def self.#{action}!(options={}, &block) define_method :__#{action}, &block class_eval <<-ACTION def #{action} super(\#{options.inspect}, &method(:__#{action})) end ACTION end WRITTER end end end end inherited_resources-1.13.0/lib/inherited_resources/engine.rb000066400000000000000000000005271404526035200242530ustar00rootroot00000000000000module InheritedResources class Railtie < ::Rails::Engine config.inherited_resources = InheritedResources if config.respond_to?(:app_generators) config.app_generators.scaffold_controller = :inherited_resources_controller else config.generators.scaffold_controller = :inherited_resources_controller end end end inherited_resources-1.13.0/lib/inherited_resources/polymorphic_helpers.rb000066400000000000000000000125431404526035200270760ustar00rootroot00000000000000module InheritedResources # = polymorphic associations # # In some cases you have a resource that belongs to two different resources # but not at the same time. For example, let's suppose you have File, Message # and Task as resources and they are all commentable. # # Polymorphic associations allows you to create just one controller that will # deal with each case. # # class Comment < InheritedResources::Base # belongs_to :file, :message, :task, :polymorphic => true # end # # Your routes should be something like: # # resources :files do # resources :comments #=> /files/13/comments # end # resources :tasks do # resources :comments #=> /tasks/17/comments # end # resources :messages do # resources :comments #=> /messages/11/comments # end # # When using polymorphic associations, you get some free helpers: # # parent? #=> true # parent_type #=> :task # parent_class #=> Task # parent #=> @task # # This polymorphic controllers thing is a great idea by James Golick and he # built it in resource_controller. Here is just a re-implementation. # # = optional polymorphic associations # # Let's take another break from ProjectsController. Let's suppose we are # building a store, which sell products. # # On the website, we can show all products, but also products scoped to # categories, brands, users. In this case case, the association is optional, and # we deal with it in the following way: # # class ProductsController < InheritedResources::Base # belongs_to :category, :brand, :user, :polymorphic => true, :optional => true # end # # This will handle all those urls properly: # # /products/1 # /categories/2/products/5 # /brands/10/products/3 # /user/13/products/11 # # = nested polymorphic associations # # You can have polymorphic associations with nested resources. Let's suppose # that our File, Task and Message resources in the previous example belongs to # a project. # # This way we can have: # # class CommentsController < InheritedResources::Base # belongs_to :project { # belongs_to :file, :message, :task, :polymorphic => true # } # end # # Or: # # class CommentsController < InheritedResources::Base # nested_belongs_to :project # nested_belongs_to :file, :message, :task, :polymorphic => true # end # # Choose the syntax that makes more sense to you. :) # # Finally your routes should be something like: # # resources :projects do # resources :files do # resources :comments #=> /projects/1/files/13/comments # end # resources :tasks do # resources :comments #=> /projects/1/tasks/17/comments # end # resources :messages do # resources :comments #=> /projects/1/messages/11/comments # end # end # # The helpers work in the same way as above. # module PolymorphicHelpers protected # Returns the parent type. A Comments class can have :task, :file, :note # as parent types. # def parent_type unless instance_variable_defined?(:@parent_type) symbols_for_association_chain end if instance_variable_defined?(:@parent_type) @parent_type end end def parent_class parent.class if parent_type end # Returns the parent object. They are also available with the instance # variable name: @task, @file, @note... # def parent if parent_type p = instance_variable_defined?("@#{parent_type}") && instance_variable_get("@#{parent_type}") p || instance_variable_set("@#{parent_type}", association_chain[-1]) end end # If the polymorphic association is optional, we might not have a parent. # def parent? if resources_configuration[:polymorphic][:optional] parents_symbols.size > 1 || !parent_type.nil? else true end end private # Maps parents_symbols to build association chain. # # If the parents_symbols find :polymorphic, it goes through the # params keys to see which polymorphic parent matches the given params. # # When optional is given, it does not raise errors if the polymorphic # params are missing. # def symbols_for_association_chain #:nodoc: polymorphic_config = resources_configuration[:polymorphic] parents_symbols.map do |symbol| if symbol == :polymorphic params_keys = params.keys keys = polymorphic_config[:symbols].map do |poly| params_keys.include?(resources_configuration[poly][:param].to_s) ? poly : nil end.compact if keys.empty? raise ScriptError, "Could not find param for polymorphic association. The request " << "parameters are #{params.keys.inspect} and the polymorphic " << "associations are #{polymorphic_config[:symbols].inspect}." unless polymorphic_config[:optional] nil else @parent_type = keys[-1].to_sym @parent_types = keys.map(&:to_sym) end else symbol end end.flatten.compact end end end inherited_resources-1.13.0/lib/inherited_resources/responder.rb000066400000000000000000000001731404526035200250040ustar00rootroot00000000000000module InheritedResources class Responder < ActionController::Responder include Responders::FlashResponder end end inherited_resources-1.13.0/lib/inherited_resources/shallow_helpers.rb000066400000000000000000000030651404526035200262010ustar00rootroot00000000000000module InheritedResources # Shallow provides a functionality that goes on pair with Rails' shallow. # It is very similar to "optional" but it actually finds all the parents # resources instead of leaving them blank. Consider the following example: # # belongs_to :post, :shallow => true do # belongs_to :comment # end # # When accessed as /comments/1, Inherited Resources will automatically get # the post resource so both objects are actually accessible through the views. # # However, when using optional, Inherited Resources wouldn't actually bother # with finding the parent object. module ShallowHelpers private def symbols_for_association_chain #:nodoc: parent_symbols = parents_symbols.dup instance = nil if id = params[:id] finder_method = resources_configuration[:self][:finder] || :find instance = self.resource_class.send(finder_method, id) elsif parents_symbols.size > 1 config = resources_configuration[parent_symbols.pop] finder_method = config[:finder] || :find instance = config[:parent_class].send(finder_method, params[config[:param]]) end load_parents(instance, parent_symbols) if instance parents_symbols end def load_parents(instance, parent_symbols) parent_symbols.reverse.each do |parent| instance = instance.send(parent) config = resources_configuration[parent] params[config[:param]] = instance.to_param end end end end inherited_resources-1.13.0/lib/inherited_resources/singleton_helpers.rb000066400000000000000000000051141404526035200265270ustar00rootroot00000000000000module InheritedResources # = singleton # # Singletons are usually used in associations which are related through has_one # and belongs_to. You declare those associations like this: # # class ManagersController < InheritedResources::Base # belongs_to :project, :singleton => true # end # # But in some cases, like an AccountsController, you have a singleton object # that is not necessarily associated with another: # # class AccountsController < InheritedResources::Base # defaults :singleton => true # end # # Besides that, you should overwrite the methods :resource and :build_resource # to make it work properly: # # class AccountsController < InheritedResources::Base # defaults :singleton => true # # protected # def resource # @current_user.account # end # # def build_resource(attributes = {}) # Account.new(attributes) # end # end # # When you have a singleton controller, the action index is removed. # module SingletonHelpers protected # Singleton methods does not deal with collections. # def collection nil end # Overwrites how singleton deals with resource. # # If you are going to overwrite it, you should notice that the # end_of_association_chain here is not the same as in default belongs_to. # # class TasksController < InheritedResources::Base # belongs_to :project # end # # In this case, the association chain would be: # # Project.find(params[:project_id]).tasks # # So you would just have to call find(:all) at the end of association # chain. And this is what happened. # # In singleton controllers: # # class ManagersController < InheritedResources::Base # belongs_to :project, :singleton => true # end # # The association chain will be: # # Project.find(params[:project_id]) # # So we have to call manager on it, not find. # def resource get_resource_ivar || set_resource_ivar(end_of_association_chain.send(resource_instance_name)) end private # Returns the appropriated method to build the resource. # def method_for_association_build #:nodoc: :"build_#{resource_instance_name}" end # Sets the method_for_association_chain to nil. See resource # above for more information. # def method_for_association_chain #:nodoc: nil end end end inherited_resources-1.13.0/lib/inherited_resources/url_helpers.rb000066400000000000000000000226411404526035200253330ustar00rootroot00000000000000module InheritedResources # = URLHelpers # # When you use InheritedResources it creates some UrlHelpers for you. # And they handle everything for you. # # # /posts/1/comments # resource_url # => /posts/1/comments/#{@comment.to_param} # resource_url(comment) # => /posts/1/comments/#{comment.to_param} # new_resource_url # => /posts/1/comments/new # edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit # collection_url # => /posts/1/comments # parent_url # => /posts/1 # # # /projects/1/tasks # resource_url # => /projects/1/tasks/#{@task.to_param} # resource_url(task) # => /projects/1/tasks/#{task.to_param} # new_resource_url # => /projects/1/tasks/new # edit_resource_url # => /projects/1/tasks/#{@task.to_param}/edit # collection_url # => /projects/1/tasks # parent_url # => /projects/1 # # # /users # resource_url # => /users/#{@user.to_param} # resource_url(user) # => /users/#{user.to_param} # new_resource_url # => /users/new # edit_resource_url # => /users/#{@user.to_param}/edit # collection_url # => /users # parent_url # => / # # The nice thing is that those urls are not guessed during runtime. They are # all created when you inherit. # module UrlHelpers protected # This method hard code url helpers in the class. # # We are doing this because is cheaper than guessing them when our action # is being processed (and even more cheaper when we are using nested # resources). # # When we are using polymorphic associations, those helpers rely on # polymorphic_url Rails helper. # def create_resources_url_helpers! resource_segments, resource_ivars = [], [] resource_config = self.resources_configuration[:self] singleton = resource_config[:singleton] uncountable = !singleton && resource_config[:route_collection_name] == resource_config[:route_instance_name] polymorphic = self.parents_symbols.include?(:polymorphic) # Add route_prefix if any. unless resource_config[:route_prefix].blank? if polymorphic resource_ivars << resource_config[:route_prefix] else resource_segments << resource_config[:route_prefix] end end # Deal with belongs_to associations and polymorphic associations. # Remember that we don't have to build the segments in polymorphic cases, # because the url will be polymorphic_url. # self.parents_symbols.each do |symbol| if symbol == :polymorphic resource_ivars << :parent else config = self.resources_configuration[symbol] if config[:singleton] && polymorphic resource_ivars << config[:instance_name] else resource_segments << config[:route_name] end if !config[:singleton] resource_ivars << :"@#{config[:instance_name]}" end end end collection_ivars = resource_ivars.dup collection_segments = resource_segments.dup # Generate parent url before we add resource instances. unless parents_symbols.empty? generate_url_and_path_helpers nil, :parent, resource_segments, resource_ivars generate_url_and_path_helpers :edit, :parent, resource_segments, resource_ivars end # In singleton cases, we do not send the current element instance variable # because the id is not in the URL. For example, we should call: # # project_manager_url(@project) # # Instead of: # # project_manager_url(@project, @manager) # # Another exception in singleton cases is that collection url does not # exist. In such cases, we create the parent collection url. So in the # manager case above, the collection url will be: # # project_url(@project) # # If the singleton does not have a parent, it will default to root_url. # collection_segments << resource_config[:route_collection_name] unless singleton resource_segments << resource_config[:route_instance_name] resource_ivars << :"@#{resource_config[:instance_name]}" unless singleton # Finally, polymorphic cases we have to give hints to the polymorphic url # builder. This works by attaching new ivars as symbols or records. # if polymorphic && singleton resource_ivars << resource_config[:instance_name] new_ivars = resource_ivars end # If route is uncountable then add "_index" suffix to collection index route name if uncountable collection_segments << :"#{collection_segments.pop}_index" end generate_url_and_path_helpers nil, :collection, collection_segments, collection_ivars generate_url_and_path_helpers :new, :resource, resource_segments, new_ivars || collection_ivars generate_url_and_path_helpers nil, :resource, resource_segments, resource_ivars generate_url_and_path_helpers :edit, :resource, resource_segments, resource_ivars if resource_config[:custom_actions] [*resource_config[:custom_actions][:resource]].each do | method | generate_url_and_path_helpers method, :resource, resource_segments, resource_ivars end [*resource_config[:custom_actions][:collection]].each do | method | generate_url_and_path_helpers method, :resources, collection_segments, collection_ivars end end end def handle_shallow_resource(prefix, name, segments, ivars) #:nodoc: return segments, ivars unless self.resources_configuration[:self][:shallow] case name when :collection, :resources segments = segments[-2..-1] ivars = [ivars.last] when :resource if prefix == :new segments = segments[-2..-1] ivars = [ivars.last] else segments = [segments.last] ivars = [ivars.last] end when :parent segments = [segments.last] ivars = [ivars.last] end segments ||= [] unless self.resources_configuration[:self][:route_prefix].blank? segments.unshift self.resources_configuration[:self][:route_prefix] end return segments, ivars end def generate_url_and_path_helpers(prefix, name, resource_segments, resource_ivars) #:nodoc: resource_segments, resource_ivars = handle_shallow_resource(prefix, name, resource_segments, resource_ivars) ivars = resource_ivars.dup singleton = self.resources_configuration[:self][:singleton] polymorphic = self.parents_symbols.include?(:polymorphic) # In collection in polymorphic cases, allow an argument to be given as a # replacemente for the parent. # parent_index = ivars.index(:parent) if polymorphic segments = if polymorphic :polymorphic elsif resource_segments.empty? 'root' else resource_segments.join('_') end define_params_helper(prefix, name, singleton, polymorphic, parent_index, ivars) define_helper_method(prefix, name, :path, segments) define_helper_method(prefix, name, :url, segments) end def define_params_helper(prefix, name, singleton, polymorphic, parent_index, ivars) params_method_name = ['', prefix, name, :params].compact.join('_') undef_method params_method_name if method_defined? params_method_name define_method params_method_name do |*given_args| given_args = given_args.collect { |arg| arg.respond_to?(:permitted?) ? arg.to_h : arg } given_options = given_args.extract_options! args = ivars.map do |ivar| ivar.is_a?(Symbol) && ivar.to_s.start_with?('@') ? instance_variable_get(ivar) : ivar end args[parent_index] = parent if parent_index if !(singleton && name != :parent) && args.present? && name != :collection && prefix != :new resource = args.pop args.push(given_args.first || resource) end if polymorphic if name == :collection args[parent_index] = given_args.present? ? given_args.first : parent end if (name == :collection || name == :resource && prefix == :new) && !singleton args << (@_resource_class_new ||= resource_class.new) end args.compact! if self.resources_configuration[:polymorphic][:optional] args = [args] end args << given_options end protected params_method_name end def define_helper_method(prefix, name, suffix, segments) method_name = [prefix, name, suffix].compact.join('_') params_method_name = ['', prefix, name, :params].compact.join('_') segments_method = [prefix, segments, suffix].compact.join('_') undef_method method_name if method_defined? method_name define_method method_name do |*given_args| given_args = send params_method_name, *given_args send segments_method, *given_args end protected method_name end end end inherited_resources-1.13.0/lib/inherited_resources/version.rb000066400000000000000000000000721404526035200244660ustar00rootroot00000000000000module InheritedResources VERSION = '1.13.0'.freeze end inherited_resources-1.13.0/tasks/000077500000000000000000000000001404526035200167675ustar00rootroot00000000000000inherited_resources-1.13.0/tasks/gemfiles.rake000066400000000000000000000003641404526035200214310ustar00rootroot00000000000000desc "Bundle all Gemfiles" task :bundle do |_t, opts| ["Gemfile", *Dir.glob("test/rails_[5-9][0-9]/Gemfile")].each do |gemfile| Bundler.with_original_env do system({ "BUNDLE_GEMFILE" => gemfile }, "bundle", *opts) end end end inherited_resources-1.13.0/tasks/release.rake000066400000000000000000000002011404526035200212440ustar00rootroot00000000000000require "chandler/tasks" # # Add chandler as a prerequisite for `rake release` # task "release:rubygem_push" => "chandler:push" inherited_resources-1.13.0/test/000077500000000000000000000000001404526035200166215ustar00rootroot00000000000000inherited_resources-1.13.0/test/aliases_test.rb000066400000000000000000000105701404526035200216310ustar00rootroot00000000000000require 'test_helper' class Student extend ActiveModel::Naming end class ApplicationController < ActionController::Base include InheritedResources::DSL end class StudentsController < ApplicationController inherit_resources respond_to :html, :xml def edit edit! do |format| format.xml { render plain: 'Render XML' } end end def new @something = 'magical' new! end create!(location: "http://test.host/") do |success, failure| success.html { render plain: "I won't redirect!" } failure.xml { render plain: "I shouldn't be rendered" } end update! do |success, failure| success.html { redirect_to(resource_url) } failure.html { render plain: "I won't render!" } end destroy! do |format| format.html { render plain: "Destroyed!" } end end class AliasesTest < ActionController::TestCase tests StudentsController def setup draw_routes do resources :students end end def teardown clear_routes end def test_assignments_before_calling_alias Student.stubs(:new).returns(mock_student) get :new assert_response :success assert_equal 'magical', assigns(:something) end def test_controller_should_render_new Student.stubs(:new).returns(mock_student) get :new assert_response :success assert_equal 'New HTML', @response.body.strip end def test_expose_the_requested_user_on_edit Student.expects(:find).with('42').returns(mock_student) get :edit, params: { id: '42' } assert_equal mock_student, assigns(:student) assert_response :success end def test_controller_should_render_edit Student.stubs(:find).returns(mock_student) get :edit, params: { id: '42' } assert_response :success assert_equal 'Edit HTML', @response.body.strip end def test_render_xml_when_it_is_given_as_a_block @request.accept = 'application/xml' Student.stubs(:find).returns(mock_student) get :edit, params: { id: '42' } assert_response :success assert_equal 'Render XML', @response.body end def test_is_not_redirected_on_create_with_success_if_success_block_is_given Student.stubs(:new).returns(mock_student(save: true)) @controller.stubs(:resource_url).returns('http://test.host/') post :create assert_response :success assert_equal "I won't redirect!", @response.body end def test_dumb_responder_quietly_receives_everything_on_failure @request.accept = 'text/html' Student.stubs(:new).returns(mock_student(save: false, errors: {some: :error})) @controller.stubs(:resource_url).returns('http://test.host/') post :create assert_response :success assert_equal "New HTML", @response.body.strip end def test_html_is_the_default_when_only_xml_is_overwriten @request.accept = '*/*' Student.stubs(:new).returns(mock_student(save: false, errors: {some: :error})) @controller.stubs(:resource_url).returns('http://test.host/') post :create assert_response :success assert_equal "New HTML", @response.body.strip end def test_wont_render_edit_template_on_update_with_failure_if_failure_block_is_given Student.stubs(:find).returns(mock_student(update: false, errors: { fail: true })) put :update, params: { id: '42' } assert_response :success assert_equal "I won't render!", @response.body end def test_dumb_responder_quietly_receives_everything_on_success Student.stubs(:find).returns(mock_student(update: true)) @controller.stubs(:resource_url).returns('http://test.host/') put :update, params: { id: '42', student: {these: 'params'} } assert_equal mock_student, assigns(:student) end def test_block_is_called_when_student_is_destroyed Student.stubs(:find).returns(mock_student(destroy: true)) delete :destroy, params: { id: '42' } assert_response :success assert_equal "Destroyed!", @response.body end def test_options_are_used_in_respond_with @request.accept = "application/xml" mock_student = mock_student(save: true, to_xml: "XML") Student.stubs(:new).returns(mock_student) post :create assert_equal "http://test.host/", @response.location end protected def mock_student(expectations={}) @mock_student ||= begin student = mock(expectations.except(:errors)) student.stubs(:class).returns(Student) student.stubs(:errors).returns(expectations.fetch(:errors, {})) student end end end inherited_resources-1.13.0/test/association_chain_test.rb000066400000000000000000000064551404526035200236750ustar00rootroot00000000000000require 'test_helper' class Pet extend ActiveModel::Naming end class Puppet extend ActiveModel::Naming end class PetsController < InheritedResources::Base attr_accessor :current_user def edit @pet = 'new pet' edit! end protected def collection @pets ||= end_of_association_chain.all end def begin_of_association_chain @current_user end end class BeginOfAssociationChainTest < ActionController::TestCase tests PetsController def setup draw_routes do resources :pets end @controller.current_user = mock() end def teardown clear_routes end def test_begin_of_association_chain_is_called_on_index @controller.current_user.expects(:pets).returns(Pet) Pet.expects(:all).returns(mock_pet) get :index assert_response :success assert_equal 'Index HTML', @response.body.strip end def test_begin_of_association_chain_is_called_on_new @controller.current_user.expects(:pets).returns(Pet) Pet.expects(:build).returns(mock_pet) get :new assert_response :success assert_equal 'New HTML', @response.body.strip end def test_begin_of_association_chain_is_called_on_show @controller.current_user.expects(:pets).returns(Pet) Pet.expects(:find).with('47').returns(mock_pet) get :show, params: { id: '47' } assert_response :success assert_equal 'Show HTML', @response.body.strip end def test_instance_variable_should_not_be_set_if_already_defined @controller.current_user.expects(:pets).never Pet.expects(:find).never get :edit, params: { id: '47' } assert_response :success assert_equal 'new pet', assigns(:pet) end def test_model_is_not_initialized_with_nil @controller.current_user.expects(:pets).returns(Pet) Pet.expects(:build).with({}).returns(mock_pet) get :new assert_equal mock_pet, assigns(:pet) end def test_begin_of_association_chain_is_included_in_chain @controller.current_user.expects(:pets).returns(Pet) Pet.expects(:build).with({}).returns(mock_pet) get :new assert_equal [@controller.current_user], @controller.send(:association_chain) end protected def mock_pet(stubs={}) @mock_pet ||= mock(stubs) end end class PuppetsController < InheritedResources::Base optional_belongs_to :pet end class AssociationChainTest < ActionController::TestCase tests PuppetsController def setup draw_routes do resources :puppets end @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_parent_is_added_to_association_chain Pet.expects(:find).with('37').returns(mock_pet) mock_pet.expects(:puppets).returns(Puppet) Puppet.expects(:find).with('42').returns(mock_puppet) mock_puppet.expects(:destroy) delete :destroy, params: { id: '42', pet_id: '37' } assert_equal [mock_pet], @controller.send(:association_chain) end def test_parent_is_added_to_association_chain_if_not_available Puppet.expects(:find).with('42').returns(mock_puppet) mock_puppet.expects(:destroy) delete :destroy, params: { id: '42' } assert_equal [], @controller.send(:association_chain) end protected def mock_pet(stubs={}) @mock_pet ||= mock(stubs) end def mock_puppet(stubs={}) @mock_puppet ||= mock(stubs) end end inherited_resources-1.13.0/test/autoload/000077500000000000000000000000001404526035200204315ustar00rootroot00000000000000inherited_resources-1.13.0/test/autoload/engine.rb000066400000000000000000000000571404526035200222250ustar00rootroot00000000000000module MyTestNamespace class Engine; end end inherited_resources-1.13.0/test/base_test.rb000066400000000000000000000255771404526035200211370ustar00rootroot00000000000000require 'test_helper' class User extend ActiveModel::Naming end class AccountsController < InheritedResources::Base end class UsersController < AccountsController respond_to :html, :xml respond_to :js, only: [:create, :update, :destroy] attr_reader :scopes_applied def self.name "UsersController" end protected def apply_scopes(object) @scopes_applied = true object end end module UserTestHelper def setup draw_routes do resources :users end @controller_class = Class.new(UsersController) @controller = @controller_class.new @controller.request = @request = new_request @controller.response = @response = new_response @controller.stubs(:user_url).returns("/") end def teardown clear_routes end protected def new_request ActionController::TestRequest.create(UsersController) end def new_response ActionDispatch::TestResponse.create end def mock_user(expectations={}) @mock_user ||= begin user = mock(expectations.except(:errors)) user.stubs(:class).returns(User) user.stubs(:errors).returns(expectations.fetch(:errors, {})) user.singleton_class.class_eval do def method_missing(symbol, *arguments, &block) raise NoMethodError.new('this is expected by Array#flatten') if symbol == :to_ary super end end user end end end class IndexActionBaseTest < ActionController::TestCase include UserTestHelper def test_expose_all_users_as_instance_variable User.expects(:scoped).returns([mock_user]) get :index assert_equal [mock_user], assigns(:users) end def test_apply_scopes_if_method_is_available User.expects(:scoped).returns([mock_user]) get :index assert @controller.scopes_applied end def test_controller_should_render_index User.stubs(:scoped).returns([mock_user]) get :index assert_response :success assert_equal 'Index HTML', @response.body.strip end def test_render_all_users_as_xml_when_mime_type_is_xml @request.accept = 'application/xml' User.expects(:scoped).returns(collection = [mock_user]) collection.expects(:to_xml).returns('Generated XML') get :index assert_response :success assert_equal 'Generated XML', @response.body end def test_scoped_is_called_only_when_available User.stubs(:all).returns([mock_user]) get :index assert_equal Array, assigns(:users).class end end class ShowActionBaseTest < ActionController::TestCase include UserTestHelper def test_expose_the_requested_user User.expects(:find).with('42').returns(mock_user) get :show, params: { id: '42' } assert_equal mock_user, assigns(:user) end def test_controller_should_render_show User.stubs(:find).returns(mock_user) get :show, params: { id: '42' } assert_response :success assert_equal 'Show HTML', @response.body.strip end def test_render_exposed_user_as_xml_when_mime_type_is_xml @request.accept = 'application/xml' User.expects(:find).with('42').returns(mock_user) mock_user.expects(:to_xml).returns("Generated XML") get :show, params: { id: '42' } assert_response :success assert_equal 'Generated XML', @response.body end end class NewActionBaseTest < ActionController::TestCase include UserTestHelper def test_expose_a_new_user User.expects(:new).returns(mock_user) get :new assert_equal mock_user, assigns(:user) end def test_controller_should_render_new User.stubs(:new).returns(mock_user) get :new assert_response :success assert_equal 'New HTML', @response.body.strip end def test_render_exposed_a_new_user_as_xml_when_mime_type_is_xml @request.accept = 'application/xml' User.expects(:new).returns(mock_user) mock_user.expects(:to_xml).returns("Generated XML") get :new assert_response :success assert_equal 'Generated XML', @response.body end end class EditActionBaseTest < ActionController::TestCase include UserTestHelper def test_expose_the_requested_user User.expects(:find).with('42').returns(mock_user) get :edit, params: { id: '42' } assert_response :success assert_equal mock_user, assigns(:user) end def test_controller_should_render_edit User.stubs(:find).returns(mock_user) get :edit, params: { id: '42' } assert_response :success assert_equal 'Edit HTML', @response.body.strip end end class CreateActionBaseTest < ActionController::TestCase include UserTestHelper def test_expose_a_newly_create_user_when_saved_with_success User.expects(:new).with({'these' => 'params'}).returns(mock_user(save: true)) post :create, params: { user: {these: 'params'} } assert_equal mock_user, assigns(:user) end def test_expose_a_newly_create_user_when_saved_with_success_and_role_setted @controller.class.send(:with_role, :admin) User.expects(:new).with({'these' => 'params'}, {as: :admin}).returns(mock_user(save: true)) post :create, params: { user: {these: 'params'} } assert_equal mock_user, assigns(:user) end def test_expose_a_newly_create_user_when_saved_with_success_and_without_protection_setted @controller.class.send(:without_protection, true) User.expects(:new).with({'these' => 'params'}, {without_protection: true}).returns(mock_user(save: true)) post :create, params: { user: {these: 'params'} } assert_equal mock_user, assigns(:user) end def test_redirect_to_the_created_user User.stubs(:new).returns(mock_user(save: true)) @controller.expects(:resource_url).returns('http://test.host/') post :create, format: :html assert_redirected_to 'http://test.host/' end def test_show_flash_message_when_success User.stubs(:new).returns(mock_user(save: true)) post :create assert_equal flash[:notice], 'User was successfully created.' end def test_show_flash_message_with_javascript_request_when_success User.stubs(:new).returns(mock_user(save: true)) post :create, format: :js assert_equal flash[:notice], 'User was successfully created.' end def test_render_new_template_when_user_cannot_be_saved User.stubs(:new).returns(mock_user(save: false, errors: {some: :error})) post :create assert_response :success assert_equal "New HTML", @response.body.strip end def test_dont_show_flash_message_when_user_cannot_be_saved User.stubs(:new).returns(mock_user(save: false, errors: {some: :error})) post :create assert flash.empty? end end class UpdateActionBaseTest < ActionController::TestCase include UserTestHelper def test_update_the_requested_object User.expects(:find).with('42').returns(mock_user) mock_user.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', user: {these: 'params'} } assert_equal mock_user, assigns(:user) end def test_update_the_requested_object_when_setted_role @controller.class.send(:with_role, :admin) User.expects(:find).with('42').returns(mock_user) mock_user.expects(:update).with({'these' => 'params'}, {as: :admin}).returns(true) put :update, params: { id: '42', user: {these: 'params'} } assert_equal mock_user, assigns(:user) end def test_update_the_requested_object_when_setted_without_protection @controller.class.send(:without_protection, true) User.expects(:find).with('42').returns(mock_user) mock_user.expects(:update).with({'these' => 'params'}, {without_protection: true}).returns(true) put :update, params: { id: '42', user: {these: 'params'} } assert_equal mock_user, assigns(:user) end def test_redirect_to_the_updated_user User.stubs(:find).returns(mock_user(update: true)) @controller.expects(:resource_url).returns('http://test.host/') put :update, params: { id: '42' } assert_redirected_to 'http://test.host/' end def test_redirect_to_the_users_list_if_show_undefined @controller.class.send(:actions, :all, except: :show) User.stubs(:find).returns(mock_user(update: true)) @controller.expects(:collection_url).returns('http://test.host/') put :update, params: { id: '42' } assert_redirected_to 'http://test.host/' end def test_show_flash_message_when_success User.stubs(:find).returns(mock_user(update: true)) put :update, params: { id: '42' } assert_equal flash[:notice], 'User was successfully updated.' end def test_show_flash_message_with_javascript_request_when_success User.stubs(:find).returns(mock_user(update: true)) post :update, params: { id: '42' }, format: :js assert_equal flash[:notice], 'User was successfully updated.' end def test_render_edit_template_when_user_cannot_be_saved User.stubs(:find).returns(mock_user(update: false, errors: {some: :error})) put :update, params: { id: '42' } assert_response :success assert_equal "Edit HTML", @response.body.strip end def test_dont_show_flash_message_when_user_cannot_be_saved User.stubs(:find).returns(mock_user(update: false, errors: {some: :error})) put :update, params: { id: '42' } assert flash.empty? end end class DestroyActionBaseTest < ActionController::TestCase include UserTestHelper def test_the_requested_user_is_destroyed User.expects(:find).with('42').returns(mock_user) mock_user.expects(:destroy).returns(true) delete :destroy, params: { id: '42' } assert_equal mock_user, assigns(:user) end def test_show_flash_message_when_user_can_be_deleted User.stubs(:find).returns(mock_user(destroy: true)) delete :destroy, params: { id: '42' } assert_equal flash[:notice], 'User was successfully destroyed.' end def test_show_flash_message_with_javascript_request_when_user_can_be_deleted User.stubs(:find).returns(mock_user(destroy: true)) delete :destroy, params: { id: '42' }, format: :js assert_equal flash[:notice], 'User was successfully destroyed.' end def test_show_flash_message_when_user_cannot_be_deleted User.stubs(:find).returns(mock_user(destroy: false, errors: { fail: true })) delete :destroy, params: { id: '42' } assert_equal flash[:alert], 'User could not be destroyed.' end def test_show_flash_message_with_javascript_request_when_user_cannot_be_deleted User.stubs(:find).returns(mock_user(destroy: false, errors: { fail: true })) delete :destroy, params: { id: '42' }, format: :js assert_equal flash[:alert], 'User could not be destroyed.' end def test_redirects_to_users_list User.stubs(:find).returns(mock_user(destroy: true)) @controller.expects(:collection_url).returns('http://test.host/') delete :destroy, params: { id: '42' } assert_redirected_to 'http://test.host/' end def test_redirects_to_the_resource_if_cannot_be_destroyed User.stubs(:find).returns(mock_user(destroy: false)) @controller.expects(:collection_url).returns('http://test.host/') delete :destroy, params: { id: '42' } assert_redirected_to 'http://test.host/' end end inherited_resources-1.13.0/test/belongs_to_test.rb000066400000000000000000000111601404526035200223370ustar00rootroot00000000000000require 'test_helper' class Post extend ActiveModel::Naming end class Comment extend ActiveModel::Naming end class CommentsController < InheritedResources::Base belongs_to :post end class BelongsToTest < ActionController::TestCase tests CommentsController def setup draw_routes do resources :comments, :posts end Post.expects(:find).with('37').returns(mock_post) mock_post.expects(:comments).returns(Comment) end def teardown clear_routes end def test_expose_all_comments_as_instance_variable_on_index Comment.expects(:scoped).returns([mock_comment]) get :index, params: { post_id: '37' } assert_equal mock_post, assigns(:post) assert_equal [mock_comment], assigns(:comments) end def test_expose_the_requested_comment_on_show Comment.expects(:find).with('42').returns(mock_comment) get :show, params: { id: '42', post_id: '37' } assert_equal mock_post, assigns(:post) assert_equal mock_comment, assigns(:comment) end def test_expose_a_new_comment_on_new Comment.expects(:build).returns(mock_comment) get :new, params: { post_id: '37' } assert_equal mock_post, assigns(:post) assert_equal mock_comment, assigns(:comment) end def test_expose_the_requested_comment_on_edit Comment.expects(:find).with('42').returns(mock_comment) get :edit, params: { id: '42', post_id: '37' } assert_equal mock_post, assigns(:post) assert_equal mock_comment, assigns(:comment) end def test_expose_a_newly_create_comment_on_create Comment.expects(:build).with({'these' => 'params'}).returns(mock_comment(save: true)) post :create, params: { post_id: '37', comment: {these: 'params'} } assert_equal mock_post, assigns(:post) assert_equal mock_comment, assigns(:comment) end def test_update_the_requested_object_on_update Comment.expects(:find).with('42').returns(mock_comment) mock_comment.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', post_id: '37', comment: {these: 'params'} } assert_equal mock_post, assigns(:post) assert_equal mock_comment, assigns(:comment) end def test_the_requested_comment_is_destroyed_on_destroy Comment.expects(:find).with('42').returns(mock_comment) mock_comment.expects(:destroy) delete :destroy, params: { id: '42', post_id: '37' } assert_equal mock_post, assigns(:post) assert_equal mock_comment, assigns(:comment) end def helper_methods @controller.class._helpers.instance_methods.map {|m| m.to_s } end def test_helpers Comment.expects(:scoped).returns([mock_comment]) get :index, params: { post_id: '37' } assert helper_methods.include?('parent?') assert @controller.send(:parent?) assert_equal mock_post, assigns(:post) assert helper_methods.include?('parent') assert_equal mock_post, @controller.send(:parent) end protected def mock_post(stubs={}) @mock_post ||= mock(stubs) end def mock_comment(stubs={}) @mock_comment ||= mock(stubs) end end class Reply extend ActiveModel::Naming end class RepliesController < InheritedResources::Base belongs_to :post actions :all, except: [:show, :index] end class BelongsToWithRedirectsTest < ActionController::TestCase tests RepliesController def setup draw_routes do resources :replies, :posts end Post.expects(:find).with('37').returns(mock_post) mock_post.expects(:replies).returns(Reply) end def teardown clear_routes end def test_redirect_to_the_post_on_create_if_show_and_index_undefined @controller.expects(:parent_url).returns('http://test.host/') Reply.expects(:build).with({'these' => 'params'}).returns(mock_reply(save: true)) post :create, params: { post_id: '37', reply: { these: 'params' } } assert_redirected_to 'http://test.host/' end def test_redirect_to_the_post_on_update_if_show_and_index_undefined Reply.stubs(:find).returns(mock_reply(update: true)) @controller.expects(:parent_url).returns('http://test.host/') put :update, params: { id: '42', post_id: '37', reply: { these: 'params' } } assert_redirected_to 'http://test.host/' end def test_redirect_to_the_post_on_destroy_if_show_and_index_undefined Reply.expects(:find).with('42').returns(mock_reply) mock_reply.expects(:destroy) @controller.expects(:parent_url).returns('http://test.host/') delete :destroy, params: { id: '42', post_id: '37' } assert_redirected_to 'http://test.host/' end protected def mock_post(stubs={}) @mock_post ||= mock(stubs) end def mock_reply(stubs={}) @mock_reply ||= mock(stubs) end end inherited_resources-1.13.0/test/belongs_to_with_shallow_test.rb000066400000000000000000000051301404526035200251230ustar00rootroot00000000000000require 'test_helper' class Post extend ActiveModel::Naming end class Tag extend ActiveModel::Naming end class TagsController < InheritedResources::Base belongs_to :post, shallow: true, finder: :find_by_slug end class BelongsToWithShallowTest < ActionController::TestCase tests TagsController def setup draw_routes do resources :tags end Post.expects(:find_by_slug).with('thirty_seven').returns(mock_post) mock_post.expects(:tags).returns(Tag) @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_expose_all_tags_as_instance_variable_on_index Tag.expects(:scoped).returns([mock_tag]) get :index, params: { post_id: 'thirty_seven' } assert_equal mock_post, assigns(:post) assert_equal [mock_tag], assigns(:tags) end def test_expose_a_new_tag_on_new Tag.expects(:build).returns(mock_tag) get :new, params: { post_id: 'thirty_seven' } assert_equal mock_post, assigns(:post) assert_equal mock_tag, assigns(:tag) end def test_expose_a_newly_create_tag_on_create Tag.expects(:build).with({'these' => 'params'}).returns(mock_tag(save: true)) post :create, params: { post_id: 'thirty_seven', tag: {these: 'params'} } assert_equal mock_post, assigns(:post) assert_equal mock_tag, assigns(:tag) end def test_expose_the_requested_tag_on_show should_find_parents get :show, params: { id: '42' } assert_equal mock_post, assigns(:post) assert_equal mock_tag, assigns(:tag) end def test_expose_the_requested_tag_on_edit should_find_parents get :edit, params: { id: '42' } assert_equal mock_post, assigns(:post) assert_equal mock_tag, assigns(:tag) end def test_update_the_requested_object_on_update should_find_parents mock_tag.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', tag: {these: 'params'} } assert_equal mock_post, assigns(:post) assert_equal mock_tag, assigns(:tag) end def test_the_requested_tag_is_destroyed_on_destroy should_find_parents mock_tag.expects(:destroy) delete :destroy, params: { id: '42', post_id: '37' } assert_equal mock_post, assigns(:post) assert_equal mock_tag, assigns(:tag) end protected def should_find_parents mock_tag.expects(:post).returns(mock_post) mock_post.expects(:to_param).returns('thirty_seven') Tag.expects(:find).with('42').twice.returns(mock_tag) end def mock_post(stubs={}) @mock_post ||= mock(stubs) end def mock_tag(stubs={}) @mock_tag ||= mock(stubs) end end inherited_resources-1.13.0/test/changelog_test.rb000066400000000000000000000011401404526035200221300ustar00rootroot00000000000000require 'test_helper' class ChangelogTest < ActiveSupport::TestCase def setup path = File.join(File.dirname(__dir__), "CHANGELOG.md") @changelog = File.read(path) end def test_has_definitions_for_all_implicit_links implicit_link_names = @changelog.scan(/\[([^\]]+)\]\[\]/).flatten.uniq implicit_link_names.each do |name| assert_includes @changelog, "[#{name}]: https" end end def test_entry_does_end_with_a_punctuation lines = @changelog.each_line entries = lines.grep(/^\*/) entries.each do |entry| assert_match(/(\.|\:)$/, entry) end end end inherited_resources-1.13.0/test/class_methods_test.rb000066400000000000000000000162671404526035200230510ustar00rootroot00000000000000require 'test_helper' class Book; end class Folder; end class BooksController < InheritedResources::Base custom_actions collection: :search, resource: [:delete] actions :index, :show end class ReadersController < InheritedResources::Base actions :all, except: [ :edit, :update ] end class FoldersController < InheritedResources::Base end class Dean def self.human_name; 'Dean'; end end class DeansController < InheritedResources::Base belongs_to :school end module Controller class User; end class UsersController < InheritedResources::Base; end module Admin class UsersController < InheritedResources::Base; end end end class ControllerGroup; end module Controller class GroupsController < InheritedResources::Base; end end module Library class Base end class Category end class Subcategory end class SubcategoriesController < InheritedResources::Base end end module MyEngine class Engine < Rails::Engine isolate_namespace MyEngine end class PeopleController < InheritedResources::Base; end end module MyNamespace class PeopleController < InheritedResources::Base; end end module EmptyNamespace; end class ActionsClassMethodTest < ActionController::TestCase tests BooksController def setup draw_routes do resources :books end end def teardown clear_routes end def test_cannot_render_actions assert_raise AbstractController::ActionNotFound do get :new end end def test_actions_are_undefined action_methods = BooksController.send(:action_methods).map(&:to_sym) assert_equal 4, action_methods.size [:index, :show, :delete, :search].each do |action| assert action_methods.include?(action) end instance_methods = BooksController.send(:instance_methods).map(&:to_sym) [:new, :edit, :create, :update, :destroy].each do |action| assert !instance_methods.include?(action) end end def test_actions_are_undefined_when_except_option_is_given action_methods = ReadersController.send(:action_methods) assert_equal 5, action_methods.size ['index', 'new', 'show', 'create', 'destroy'].each do |action| assert action_methods.include? action end end end class DefaultsClassMethodTest < ActiveSupport::TestCase def test_resource_class_is_set_to_nil_when_resource_model_cannot_be_found assert_nil ReadersController.send(:resource_class) end def test_defaults_are_set assert_equal Folder, FoldersController.send(:resource_class) assert_equal :folder, FoldersController.send(:resources_configuration)[:self][:instance_name] assert_equal :folders, FoldersController.send(:resources_configuration)[:self][:collection_name] end def test_defaults_can_be_overwriten BooksController.send(:defaults, resource_class: String, instance_name: 'string', collection_name: 'strings') assert_equal String, BooksController.send(:resource_class) assert_equal :string, BooksController.send(:resources_configuration)[:self][:instance_name] assert_equal :strings, BooksController.send(:resources_configuration)[:self][:collection_name] BooksController.send(:defaults, class_name: 'Integer', instance_name: :integer, collection_name: :integers) assert_equal Integer, BooksController.send(:resource_class) assert_equal :integer, BooksController.send(:resources_configuration)[:self][:instance_name] assert_equal :integers, BooksController.send(:resources_configuration)[:self][:collection_name] end def test_defaults_raises_invalid_key assert_raise ArgumentError do BooksController.send(:defaults, boom: String) end end def test_url_helpers_are_recreated_when_defaults_change BooksController.expects(:create_resources_url_helpers!).returns(true).once BooksController.send(:defaults, instance_name: 'string', collection_name: 'strings') end end class BelongsToErrorsTest < ActiveSupport::TestCase def test_belongs_to_raise_errors_with_invalid_arguments assert_raise ArgumentError do DeansController.send(:belongs_to) end assert_raise ArgumentError do DeansController.send(:belongs_to, :nice, invalid_key: '') end end def test_belongs_to_raises_an_error_when_multiple_associations_are_given_with_options assert_raise ArgumentError do DeansController.send(:belongs_to, :arguments, :with_options, parent_class: Book) end end def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_block DeansController.expects(:create_resources_url_helpers!).returns(true).once DeansController.send(:belongs_to, :school) do belongs_to :association end ensure DeansController.send(:parents_symbols=, [:school]) end def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_multiple_blocks DeansController.expects(:create_resources_url_helpers!).returns(true).once DeansController.send(:belongs_to, :school) do belongs_to :association do belongs_to :nested end end ensure DeansController.send(:parents_symbols=, [:school]) end def test_belongs_to_for_namespaced_controller_and_namespaced_model_fetches_model_in_the_namespace_firstly Library::SubcategoriesController.send(:belongs_to, :category) assert_equal Library::Category, Library::SubcategoriesController.resources_configuration[:category][:parent_class] end def test_belongs_to_for_namespaced_controller_and_non_namespaced_model_sets_parent_class_properly Library::SubcategoriesController.send(:belongs_to, :book) assert_equal Book, Library::SubcategoriesController.resources_configuration[:book][:parent_class] end def test_belongs_to_for_namespaced_model_sets_parent_class_properly Library::SubcategoriesController.send(:belongs_to, :library, class_name: 'Library::Base') assert_equal Library::Base, Library::SubcategoriesController.resources_configuration[:library][:parent_class] end def test_belongs_to_without_namespace_sets_parent_class_properly FoldersController.send(:belongs_to, :book) assert_equal Book, FoldersController.resources_configuration[:book][:parent_class] end end class SpecialCasesClassMethodTest < ActionController::TestCase def test_resource_class_to_corresponding_model_class assert_equal Controller::User, Controller::UsersController.send(:resource_class) assert_equal Controller::User, Controller::Admin::UsersController.send(:resource_class) assert_equal ControllerGroup, Controller::GroupsController.send(:resource_class) end end class MountableEngineTest < ActiveSupport::TestCase def test_route_prefix_do_not_include_engine_name puts MyEngine::PeopleController.send(:resources_configuration)[:self][:route_prefix] assert_nil MyEngine::PeopleController.send(:resources_configuration)[:self][:route_prefix] end def test_route_prefix_present_when_parent_module_is_not_a_engine assert_equal :my_namespace, MyNamespace::PeopleController.send(:resources_configuration)[:self][:route_prefix] end end class EngineLoadErrorTest < ActiveSupport::TestCase def test_does_not_crash_on_engine_load_error ActiveSupport::Dependencies.autoload_paths << 'test/autoload' EmptyNamespace.class_eval <<-RUBY class PeopleController < InheritedResources::Base; end RUBY end end inherited_resources-1.13.0/test/customized_base_test.rb000066400000000000000000000115721404526035200233730ustar00rootroot00000000000000require 'test_helper' class Car extend ActiveModel::Naming end class CarsController < InheritedResources::Base respond_to :html protected def collection @cars ||= Car.get_all end def build_resource @car ||= Car.create_new(params[:car]) end def resource @car ||= Car.get(params[:id]) end def create_resource(resource) resource.save_successfully end def update_resource(resource, attributes) resource.update_successfully(*attributes) end def destroy_resource(resource) resource.destroy_successfully end end module CarTestHelper def setup draw_routes do resources :cars end @controller = CarsController.new @controller.request = @request = new_request @controller.response = @response = new_response @controller.stubs(:car_url).returns("/") end def teardown clear_routes end protected def new_request ActionController::TestRequest.create(CarsController) end def new_response ActionDispatch::TestResponse.create end def mock_car(expectations={}) @mock_car ||= begin car = mock(expectations.except(:errors)) car.stubs(:class).returns(Car) car.stubs(:errors).returns(expectations.fetch(:errors, {})) car end end end class IndexActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_expose_all_users_as_instance_variable Car.expects(:get_all).returns([mock_car]) get :index assert_equal [mock_car], assigns(:cars) end end class ShowActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_expose_the_requested_user Car.expects(:get).with('42').returns(mock_car) get :show, params: { id: '42' } assert_equal mock_car, assigns(:car) end end class NewActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_expose_a_new_user Car.expects(:create_new).returns(mock_car) get :new assert_equal mock_car, assigns(:car) end end class EditActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_expose_the_requested_user Car.expects(:get).with('42').returns(mock_car) get :edit, params: { id: '42' } assert_response :success assert_equal mock_car, assigns(:car) end end class CreateActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_expose_a_newly_create_user_when_saved_with_success Car.expects(:create_new).with({'these' => 'params'}).returns(mock_car(save_successfully: true)) post :create, params: { car: {these: 'params'} } assert_equal mock_car, assigns(:car) end def test_redirect_to_the_created_user Car.stubs(:create_new).returns(mock_car(save_successfully: true)) @controller.expects(:resource_url).returns('http://test.host/') post :create assert_redirected_to 'http://test.host/' end def test_render_new_template_when_user_cannot_be_saved Car.stubs(:create_new).returns(mock_car(save_successfully: false, errors: {some: :error})) post :create assert_response :success assert_equal "New HTML", @response.body.strip end end class UpdateActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_update_the_requested_object Car.expects(:get).with('42').returns(mock_car) mock_car.expects(:update_successfully).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', car: {these: 'params'} } assert_equal mock_car, assigns(:car) end def test_redirect_to_the_created_user Car.stubs(:get).returns(mock_car(update_successfully: true)) @controller.expects(:resource_url).returns('http://test.host/') put :update, params: { id: '42' } assert_redirected_to 'http://test.host/' end def test_render_edit_template_when_user_cannot_be_saved Car.stubs(:get).returns(mock_car(update_successfully: false, errors: {some: :error})) put :update, params: { id: '42' } assert_response :success assert_equal "Edit HTML", @response.body.strip end end class DestroyActionCustomizedBaseTest < ActionController::TestCase include CarTestHelper def test_the_requested_user_is_destroyed Car.expects(:get).with('42').returns(mock_car) mock_car.expects(:destroy_successfully) delete :destroy, params: { id: '42' } assert_equal mock_car, assigns(:car) end def test_show_flash_message_when_user_can_be_deleted Car.stubs(:get).returns(mock_car(destroy_successfully: true)) delete :destroy, params: { id: '42' } assert_equal flash[:notice], 'Car was successfully destroyed.' end def test_show_flash_message_when_cannot_be_deleted Car.stubs(:get).returns(mock_car(destroy_successfully: false, errors: { fail: true })) delete :destroy, params: { id: '42' } assert_equal flash[:alert], 'Car could not be destroyed.' end end inherited_resources-1.13.0/test/customized_belongs_to_test.rb000066400000000000000000000050311404526035200246050ustar00rootroot00000000000000require 'test_helper' class GreatSchool end class Professor def self.human_name; 'Professor'; end end class ProfessorsController < InheritedResources::Base belongs_to :school, parent_class: GreatSchool, instance_name: :great_school, finder: :find_by_title!, param: :school_title end class CustomizedBelongsToTest < ActionController::TestCase tests ProfessorsController def setup draw_routes do resources :professors end GreatSchool.expects(:find_by_title!).with('nice').returns(mock_school(professors: Professor)) @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_expose_the_requested_school_with_chosen_instance_variable_on_index Professor.stubs(:scoped).returns([mock_professor]) get :index, params: { school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end def test_expose_the_requested_school_with_chosen_instance_variable_on_show Professor.stubs(:find).returns(mock_professor) get :show, params: { id: 42, school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end def test_expose_the_requested_school_with_chosen_instance_variable_on_new Professor.stubs(:build).returns(mock_professor) get :new, params: { school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end def test_expose_the_requested_school_with_chosen_instance_variable_on_edit Professor.stubs(:find).returns(mock_professor) get :edit, params: { id: 42, school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end def test_expose_the_requested_school_with_chosen_instance_variable_on_create Professor.stubs(:build).returns(mock_professor(save: true)) post :create, params: { school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end def test_expose_the_requested_school_with_chosen_instance_variable_on_update Professor.stubs(:find).returns(mock_professor(update: true)) put :update, params: { id: 42, school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end def test_expose_the_requested_school_with_chosen_instance_variable_on_destroy Professor.stubs(:find).returns(mock_professor(destroy: true)) delete :destroy, params: { id: 42, school_title: 'nice' } assert_equal mock_school, assigns(:great_school) end protected def mock_school(stubs={}) @mock_school ||= mock(stubs) end def mock_professor(stubs={}) @mock_professor ||= mock(stubs) end end inherited_resources-1.13.0/test/customized_redirect_to_test.rb000066400000000000000000000016251404526035200247620ustar00rootroot00000000000000require 'test_helper' class Post; def self.human_name; 'Post'; end end class PostsController < InheritedResources::Base actions :all, except: [:show] end class RedirectToIndexWithoutShowTest < ActionController::TestCase tests PostsController def setup draw_routes do resources :posts end end def teardown clear_routes end def test_redirect_index_url_after_create Post.stubs(:new).returns(mock_machine(save: true)) assert !PostsController.respond_to?(:show) post :create assert_redirected_to 'http://test.host/posts' end def test_redirect_to_index_url_after_update Post.stubs(:find).returns(mock_machine(update: true)) assert !PostsController.respond_to?(:show) put :update, params: { id: '42' } assert_redirected_to 'http://test.host/posts' end protected def mock_machine(stubs={}) @mock_machine ||= mock(stubs) end end inherited_resources-1.13.0/test/defaults_test.rb000066400000000000000000000146411404526035200220220ustar00rootroot00000000000000require 'test_helper' class Malarz def self.human_name; 'Painter'; end def to_param self.slug end end class PaintersController < InheritedResources::Base defaults instance_name: 'malarz', collection_name: 'malarze', resource_class: Malarz, route_prefix: nil, finder: :find_by_slug end class DefaultsTest < ActionController::TestCase tests PaintersController def setup draw_routes do resources :painters end end def teardown clear_routes end def test_expose_all_painters_as_instance_variable Malarz.expects(:scoped).returns([mock_painter]) get :index assert_equal [mock_painter], assigns(:malarze) end def test_expose_the_requested_painter_on_show Malarz.expects(:find_by_slug).with('forty_two').returns(mock_painter) get :show, params: { id: 'forty_two' } assert_equal mock_painter, assigns(:malarz) end def test_expose_a_new_painter Malarz.expects(:new).returns(mock_painter) get :new assert_equal mock_painter, assigns(:malarz) end def test_expose_the_requested_painter_on_edit Malarz.expects(:find_by_slug).with('forty_two').returns(mock_painter) get :edit, params: { id: 'forty_two' } assert_response :success assert_equal mock_painter, assigns(:malarz) end def test_expose_a_newly_create_painter_when_saved_with_success Malarz.expects(:new).with({'these' => 'params'}).returns(mock_painter(save: true)) post :create, params: { malarz: {these: 'params'} } assert_equal mock_painter, assigns(:malarz) end def test_update_the_requested_object Malarz.expects(:find_by_slug).with('forty_two').returns(mock_painter) mock_painter.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: 'forty_two', malarz: {these: 'params'} } assert_equal mock_painter, assigns(:malarz) end def test_the_requested_painter_is_destroyed Malarz.expects(:find_by_slug).with('forty_two').returns(mock_painter) mock_painter.expects(:destroy) delete :destroy, params: { id: 'forty_two' } assert_equal mock_painter, assigns(:malarz) end protected def mock_painter(stubs={}) @mock_painter ||= mock(stubs) end end class Lecturer def self.human_name; 'Einstein'; end end module University; end class University::LecturersController < InheritedResources::Base defaults finder: :find_by_slug end class DefaultsNamespaceTest < ActionController::TestCase tests University::LecturersController def setup draw_routes do namespace :university do resources :lecturers end end end def teardown clear_routes end def test_expose_all_lecturers_as_instance_variable Lecturer.expects(:scoped).returns([mock_lecturer]) get :index assert_equal [mock_lecturer], assigns(:lecturers) end def test_expose_the_requested_lecturer_on_show Lecturer.expects(:find_by_slug).with('forty_two').returns(mock_lecturer) get :show, params: { id: 'forty_two' } assert_equal mock_lecturer, assigns(:lecturer) end def test_expose_a_new_lecturer Lecturer.expects(:new).returns(mock_lecturer) get :new assert_equal mock_lecturer, assigns(:lecturer) end def test_expose_the_requested_lecturer_on_edit Lecturer.expects(:find_by_slug).with('forty_two').returns(mock_lecturer) get :edit, params: { id: 'forty_two' } assert_response :success assert_equal mock_lecturer, assigns(:lecturer) end def test_expose_a_newly_create_lecturer_when_saved_with_success Lecturer.expects(:new).with({'these' => 'params'}).returns(mock_lecturer(save: true)) post :create, params: { lecturer: {these: 'params'} } assert_equal mock_lecturer, assigns(:lecturer) end def test_update_the_lecturer Lecturer.expects(:find_by_slug).with('forty_two').returns(mock_lecturer) mock_lecturer.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: 'forty_two', lecturer: {these: 'params'} } assert_equal mock_lecturer, assigns(:lecturer) end def test_the_requested_lecturer_is_destroyed Lecturer.expects(:find_by_slug).with('forty_two').returns(mock_lecturer) mock_lecturer.expects(:destroy) delete :destroy, params: { id: 'forty_two' } assert_equal mock_lecturer, assigns(:lecturer) end protected def mock_lecturer(stubs={}) @mock_lecturer ||= mock(stubs) end end class Group end class AdminGroup end module Admin; end class Admin::Group end class Admin::GroupsController < InheritedResources::Base end class NamespacedModelForNamespacedController < ActionController::TestCase tests Admin::GroupsController def test_that_it_picked_the_namespaced_model # make public so we can test it Admin::GroupsController.send(:public, :resource_class) assert_equal Admin::Group, @controller.resource_class end end class Role end class AdminRole end class Admin::RolesController < InheritedResources::Base end class TwoPartNameModelForNamespacedController < ActionController::TestCase tests Admin::RolesController def test_that_it_picked_the_camelcased_model # make public so we can test it Admin::RolesController.send(:public, :resource_class) assert_equal AdminRole, @controller.resource_class end end class User end class Admin::UsersController < InheritedResources::Base end class AnotherTwoPartNameModelForNamespacedController < ActionController::TestCase tests Admin::UsersController def test_that_it_picked_the_camelcased_model # make public so we can test it Admin::UsersController.send(:public, :resource_class) assert_equal User, @controller.resource_class end def test_that_it_got_the_request_params_right # make public so we can test it Admin::UsersController.send(:public, :resources_configuration) assert_equal 'user', @controller.resources_configuration[:self][:request_name] end end module MyEngine class Engine < Rails::Engine isolate_namespace MyEngine end class Person extend ActiveModel::Naming end class PeopleController < InheritedResources::Base defaults resource_class: Person end end class IsolatedEngineModelController < ActionController::TestCase tests MyEngine::PeopleController def setup # make public so we can test it MyEngine::PeopleController.send(:public, *MyEngine::PeopleController.protected_instance_methods) end def test_isolated_model_name assert_equal 'person', @controller.resources_configuration[:self][:request_name] end end inherited_resources-1.13.0/test/gemfiles/000077500000000000000000000000001404526035200204145ustar00rootroot00000000000000inherited_resources-1.13.0/test/gemfiles/gemspec_lint.rb000066400000000000000000000006701404526035200234150ustar00rootroot00000000000000require "minitest" require "open3" require "inherited_resources/version" class GemspecTest < Minitest::Test def setup @build = Open3.capture3("gem build inherited_resources.gemspec") end def teardown File.delete("inherited_resources-#{InheritedResources::VERSION}.gem") end def test_has_no_warnings refute_includes @build[1], "WARNING" end def test_succeeds assert_equal true, @build[2].success? end end inherited_resources-1.13.0/test/gemfiles/lint.rb000066400000000000000000000010511404526035200217040ustar00rootroot00000000000000require "minitest" class GemfilesTest < Minitest::Test ["Gemfile", *Dir.glob("test/rails_[5-9][0-9]/Gemfile")].each do |gemfile| define_method :"test_#{gemfile}_is_up_to_date" do current_lockfile = File.read("#{gemfile}.lock") new_lockfile = Bundler.with_original_env do `BUNDLE_GEMFILE=#{gemfile} bundle lock --print` end msg = "Please update #{gemfile}'s lock file with `BUNDLE_GEMFILE=#{gemfile} bundle install` and commit the result" assert_equal current_lockfile, new_lockfile, msg end end end inherited_resources-1.13.0/test/locales/000077500000000000000000000000001404526035200202435ustar00rootroot00000000000000inherited_resources-1.13.0/test/locales/en.yml000066400000000000000000000007631404526035200213760ustar00rootroot00000000000000en: flash: addresses: create: notice: "You created a new address close to {{reference}}." update: notice: "Nice! {{resource_name}} was updated with success!" error: "Oh no! We could not update your address!" admin: actions: create: notice: "Admin notice message." error: "Admin error message." addresses: create: notice: "Admin, you created a new address close to {{reference}}." inherited_resources-1.13.0/test/multiple_nested_optional_belongs_to_test.rb000066400000000000000000000357721404526035200275400ustar00rootroot00000000000000require 'test_helper' class Student; end class Manager; end class Employee; end class Project def self.human_name; "Project"; end end class ProjectsController < InheritedResources::Base belongs_to :student, :manager, :employee, optional: true end class MultipleNestedOptionalTest < ActionController::TestCase tests ProjectsController def setup draw_routes do resources :projects end @controller.stubs(:resource_url).returns('/') @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end # INDEX def test_expose_all_projects_as_instance_variable_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:scoped).returns([mock_project]) get :index, params: { student_id: '37' } assert_equal mock_student, assigns(:student) assert_equal [mock_project], assigns(:projects) end def test_expose_all_projects_as_instance_variable_with_manager Manager.expects(:find).with('38').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:scoped).returns([mock_project]) get :index, params: { manager_id: '38' } assert_equal mock_manager, assigns(:manager) assert_equal [mock_project], assigns(:projects) end def test_expose_all_projects_as_instance_variable_with_employee Employee.expects(:find).with('666').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:scoped).returns([mock_project]) get :index, params: { employee_id: '666' } assert_equal mock_employee, assigns(:employee) assert_equal [mock_project], assigns(:projects) end def test_expose_all_projects_as_instance_variable_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:scoped).returns([mock_project]) get :index, params: { manager_id: '37', employee_id: '42' } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal [mock_project], assigns(:projects) end def test_expose_all_projects_as_instance_variable_without_parents Project.expects(:scoped).returns([mock_project]) get :index assert_equal [mock_project], assigns(:projects) end # SHOW def test_expose_the_requested_project_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) get :show, params: { id: '42', student_id: '37' } assert_equal mock_student, assigns(:student) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_with_manager Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) get :show, params: { id: '42', manager_id: '37' } assert_equal mock_manager, assigns(:manager) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_with_employee Employee.expects(:find).with('37').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) get :show, params: { id: '42', employee_id: '37' } assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('13').returns(mock_project) get :show, params: { id: '13', manager_id: '37', employee_id: '42' } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_without_parents Project.expects(:find).with('13').returns(mock_project) get :show, params: { id: '13' } assert_equal mock_project, assigns(:project) end # NEW def test_expose_a_new_project_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:build).returns(mock_project) get :new, params: { student_id: '37' } assert_equal mock_student, assigns(:student) assert_equal mock_project, assigns(:project) end def test_expose_a_new_project_with_manager Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:build).returns(mock_project) get :new, params: { manager_id: '37' } assert_equal mock_manager, assigns(:manager) assert_equal mock_project, assigns(:project) end def test_expose_a_new_project_with_employee Employee.expects(:find).with('37').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:build).returns(mock_project) get :new, params: { employee_id: '37' } assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_a_new_project_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:build).returns(mock_project) get :new, params: { manager_id: '37', employee_id: '42' } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_a_new_project_without_parents Project.expects(:new).returns(mock_project) get :new assert_equal mock_project, assigns(:project) end # EDIT def test_expose_the_requested_project_for_edition_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) get :edit, params: { id: '42', student_id: '37' } assert_equal mock_student, assigns(:student) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_for_edition_with_manager Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) get :edit, params: { id: '42', manager_id: '37' } assert_equal mock_manager, assigns(:manager) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_for_edition_with_employee Employee.expects(:find).with('37').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) get :edit, params: { id: '42', employee_id: '37' } assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_for_edition_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('13').returns(mock_project) get :edit, params: { id: '13', manager_id: '37', employee_id: '42' } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_the_requested_project_for_edition_without_parents Project.expects(:find).with('13').returns(mock_project) get :edit, params: { id: '13' } assert_equal mock_project, assigns(:project) end # CREATE def test_expose_a_newly_created_project_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:build).with({ 'these' => 'params' }).returns(mock_project(save: true)) post :create, params: { student_id: '37', project: { these: 'params' } } assert_equal mock_student, assigns(:student) assert_equal mock_project, assigns(:project) end def test_expose_a_newly_created_project_with_manager Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:build).with({ 'these' => 'params' }).returns(mock_project(save: true)) post :create, params: { manager_id: '37', project: { these: 'params' } } assert_equal mock_manager, assigns(:manager) assert_equal mock_project, assigns(:project) end def test_expose_a_newly_created_project_with_employee Employee.expects(:find).with('37').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:build).with({ 'these' => 'params' }).returns(mock_project(save: true)) post :create, params: { employee_id: '37', project: { these: 'params' } } assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_a_newly_created_project_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:build).with({ 'these' => 'params' }).returns(mock_project(save: true)) post :create, params: { manager_id: '37', employee_id: '42', project: { these: 'params' } } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_expose_a_newly_created_project_without_parents Project.expects(:new).with({ 'these' => 'params' }).returns(mock_project(save: true)) post :create, params: { project: { these: 'params' } } assert_equal mock_project, assigns(:project) end # UPDATE def test_update_the_requested_project_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:update).with({ 'these' => 'params' }).returns(true) put :update, params: { id: '42', student_id: '37', project: { these: 'params' } } assert_equal mock_student, assigns(:student) assert_equal mock_project, assigns(:project) end def test_update_the_requested_project_with_manager Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:update).with({ 'these' => 'params' }).returns(true) put :update, params: { id: '42', manager_id: '37', project: { these: 'params' } } assert_equal mock_manager, assigns(:manager) assert_equal mock_project, assigns(:project) end def test_update_the_requested_project_with_employee Employee.expects(:find).with('37').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:update).with({ 'these' => 'params' }).returns(true) put :update, params: { id: '42', employee_id: '37', project: { these: 'params' } } assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_update_the_requested_project_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('13').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:update).with({ 'these' => 'params' }).returns(true) put :update, params: { id: '42', manager_id: '37', employee_id: '13', project: { these: 'params' } } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end # DESTROY def test_the_requested_project_is_destroyed_with_student Student.expects(:find).with('37').returns(mock_student) mock_student.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:destroy).returns(true) delete :destroy, params: { id: '42', student_id: '37' } assert_equal mock_student, assigns(:student) assert_equal mock_project, assigns(:project) end def test_the_requested_project_is_destroyed_with_manager Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:destroy).returns(true) delete :destroy, params: { id: '42', manager_id: '37' } assert_equal mock_manager, assigns(:manager) assert_equal mock_project, assigns(:project) end def test_the_requested_project_is_destroyed_with_employee Employee.expects(:find).with('37').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:destroy).returns(true) delete :destroy, params: { id: '42', employee_id: '37' } assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_the_requested_project_is_destroyed_with_manager_and_employee Manager.expects(:find).with('37').returns(mock_manager) mock_manager.expects(:employees).returns(Employee) Employee.expects(:find).with('13').returns(mock_employee) mock_employee.expects(:projects).returns(Project) Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:destroy).returns(true) delete :destroy, params: { id: '42', manager_id: '37', employee_id: '13' } assert_equal mock_manager, assigns(:manager) assert_equal mock_employee, assigns(:employee) assert_equal mock_project, assigns(:project) end def test_the_requested_project_is_destroyed_without_parents Project.expects(:find).with('42').returns(mock_project) mock_project.expects(:destroy).returns(true) delete :destroy, params: { id: '42' } assert_equal mock_project, assigns(:project) end protected def mock_manager(stubs={}) @mock_manager ||= mock(stubs) end def mock_employee(stubs={}) @mock_employee ||= mock(stubs) end def mock_student(stubs={}) @mock_student ||= mock(stubs) end def mock_project(stubs={}) @mock_project ||= mock(stubs) end end inherited_resources-1.13.0/test/nested_belongs_to_test.rb000066400000000000000000000063541404526035200237120ustar00rootroot00000000000000require 'test_helper' class Country end class State end class City def self.human_name; 'City'; end end class CitiesController < InheritedResources::Base belongs_to :country, :state end class NestedBelongsToTest < ActionController::TestCase tests CitiesController def setup draw_routes do resources :cities end Country.expects(:find).with('13').returns(mock_country) mock_country.expects(:states).returns(State) State.expects(:find).with('37').returns(mock_state) mock_state.expects(:cities).returns(City) @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_assigns_country_and_state_and_city_on_index City.expects(:scoped).returns([mock_city]) get :index, params: { state_id: '37', country_id: '13' } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal [mock_city], assigns(:cities) end def test_assigns_country_and_state_and_city_on_show City.expects(:find).with('42').returns(mock_city) get :show, params: { id: '42', state_id: '37', country_id: '13' } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal mock_city, assigns(:city) end def test_assigns_country_and_state_and_city_on_new City.expects(:build).returns(mock_city) get :new, params: { state_id: '37', country_id: '13' } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal mock_city, assigns(:city) end def test_assigns_country_and_state_and_city_on_edit City.expects(:find).with('42').returns(mock_city) get :edit, params: { id: '42', state_id: '37', country_id: '13' } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal mock_city, assigns(:city) end def test_assigns_country_and_state_and_city_on_create City.expects(:build).with({'these' => 'params'}).returns(mock_city) mock_city.expects(:save).returns(true) post :create, params: { state_id: '37', country_id: '13', city: {these: 'params'} } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal mock_city, assigns(:city) end def test_assigns_country_and_state_and_city_on_update City.expects(:find).with('42').returns(mock_city) mock_city.expects(:update).returns(true) put :update, params: { id: '42', state_id: '37', country_id: '13', city: {these: 'params'} } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal mock_city, assigns(:city) end def test_assigns_country_and_state_and_city_on_destroy City.expects(:find).with('42').returns(mock_city) mock_city.expects(:destroy) delete :destroy, params: { id: '42', state_id: '37', country_id: '13' } assert_equal mock_country, assigns(:country) assert_equal mock_state, assigns(:state) assert_equal mock_city, assigns(:city) end protected def mock_country(stubs={}) @mock_country ||= mock(stubs) end def mock_state(stubs={}) @mock_state ||= mock(stubs) end def mock_city(stubs={}) @mock_city ||= mock(stubs) end end inherited_resources-1.13.0/test/nested_belongs_to_with_shallow_test.rb000066400000000000000000000067701404526035200265000ustar00rootroot00000000000000require 'test_helper' class Dresser end class Shelf end class Plate end class PlatesController < InheritedResources::Base belongs_to :dresser, :shelf, shallow: true end class NestedBelongsToWithShallowTest < ActionController::TestCase tests PlatesController def setup draw_routes do resources :plates end mock_shelf.expects(:dresser).returns(mock_dresser) mock_dresser.expects(:to_param).returns('13') Dresser.expects(:find).with('13').returns(mock_dresser) mock_dresser.expects(:shelves).returns(Shelf) mock_shelf.expects(:plates).returns(Plate) @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_assigns_dresser_and_shelf_and_plate_on_index Shelf.expects(:find).with('37').twice.returns(mock_shelf) Plate.expects(:scoped).returns([mock_plate]) get :index, params: { shelf_id: '37' } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal [mock_plate], assigns(:plates) end def test_assigns_dresser_and_shelf_and_plate_on_show should_find_parents get :show, params: { id: '42' } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal mock_plate, assigns(:plate) end def test_assigns_dresser_and_shelf_and_plate_on_new Plate.expects(:build).returns(mock_plate) Shelf.expects(:find).with('37').twice.returns(mock_shelf) get :new, params: { shelf_id: '37' } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal mock_plate, assigns(:plate) end def test_assigns_dresser_and_shelf_and_plate_on_edit should_find_parents get :edit, params: { id: '42' } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal mock_plate, assigns(:plate) end def test_assigns_dresser_and_shelf_and_plate_on_create Shelf.expects(:find).with('37').twice.returns(mock_shelf) Plate.expects(:build).with({'these' => 'params'}).returns(mock_plate) mock_plate.expects(:save).returns(true) post :create, params: { shelf_id: '37', plate: {these: 'params'} } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal mock_plate, assigns(:plate) end def test_assigns_dresser_and_shelf_and_plate_on_update should_find_parents mock_plate.expects(:update).returns(true) put :update, params: { id: '42', plate: {these: 'params'} } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal mock_plate, assigns(:plate) end def test_assigns_dresser_and_shelf_and_plate_on_destroy should_find_parents mock_plate.expects(:destroy) delete :destroy, params: { id: '42' } assert_equal mock_dresser, assigns(:dresser) assert_equal mock_shelf, assigns(:shelf) assert_equal mock_plate, assigns(:plate) end protected def should_find_parents Plate.expects(:find).with('42').returns(mock_plate) mock_plate.expects(:shelf).returns(mock_shelf) mock_shelf.expects(:to_param).returns('37') Plate.expects(:find).with('42').returns(mock_plate) Shelf.expects(:find).with('37').returns(mock_shelf) end def mock_dresser(stubs={}) @mock_dresser ||= mock(stubs) end def mock_shelf(stubs={}) @mock_shelf ||= mock(stubs) end def mock_plate(stubs={}) @mock_plate ||= mock(stubs) end end inherited_resources-1.13.0/test/nested_model_with_shallow_test.rb000066400000000000000000000105641404526035200254410ustar00rootroot00000000000000require 'test_helper' class Subfaculty end class Speciality end module Plan class Group end class Education end end class GroupsController < InheritedResources::Base defaults resource_class: Plan::Group, finder: :find_by_slug belongs_to :subfaculty, shallow: true do belongs_to :speciality end end class EducationsController < InheritedResources::Base defaults resource_class: Plan::Education belongs_to :subfaculty, shallow: true do belongs_to :speciality do belongs_to :group, parent_class: Plan::Group, instance_name: :plan_group, param: :group_id, finder: :find_by_slug end end end class NestedModelWithShallowTest < ActionController::TestCase tests GroupsController def setup draw_routes do resources :groups end mock_speciality.expects(:subfaculty).returns(mock_subfaculty) mock_subfaculty.expects(:to_param).returns('13') Subfaculty.expects(:find).with('13').returns(mock_subfaculty) mock_subfaculty.expects(:specialities).returns(Speciality) mock_speciality.expects(:groups).returns(Plan::Group) end def teardown clear_routes end def test_assigns_subfaculty_and_speciality_and_group_on_edit should_find_parents get :edit, params: { id: 'forty_two' } assert_equal mock_subfaculty, assigns(:subfaculty) assert_equal mock_speciality, assigns(:speciality) assert_equal mock_group, assigns(:group) end def test_expose_a_newly_create_group_with_speciality Speciality.expects(:find).with('37').twice.returns(mock_speciality) Plan::Group.expects(:build).with({'these' => 'params'}).returns(mock_group(save: true)) post :create, params: { speciality_id: '37', group: {'these' => 'params'} } assert_equal mock_group, assigns(:group) end def test_expose_a_update_group_with_speciality should_find_parents mock_group.expects(:update).with('these' => 'params').returns(true) post :update, params: { id: 'forty_two', group: {'these' => 'params'} } assert_equal mock_group, assigns(:group) end protected def should_find_parents Plan::Group.expects(:find_by_slug).with('forty_two').returns(mock_group) mock_group.expects(:speciality).returns(mock_speciality) mock_speciality.expects(:to_param).returns('37') Plan::Group.expects(:find_by_slug).with('forty_two').returns(mock_group) Speciality.expects(:find).with('37').returns(mock_speciality) end def mock_group(stubs={}) @mock_group ||= mock(stubs) end def mock_speciality(stubs={}) @mock_speciality ||= mock(stubs) end def mock_subfaculty(stubs={}) @mock_subfaculty ||= mock(stubs) end end class TwoNestedModelWithShallowTest < ActionController::TestCase tests EducationsController def setup draw_routes do resources :educations end mock_speciality.expects(:subfaculty).returns(mock_subfaculty) mock_subfaculty.expects(:to_param).returns('13') Subfaculty.expects(:find).with('13').returns(mock_subfaculty) mock_subfaculty.expects(:specialities).returns(Speciality) mock_speciality.expects(:groups).returns(Plan::Group) end def teardown clear_routes end def test_assigns_subfaculty_and_speciality_and_group_on_new should_find_parents get :new, params: { group_id: 'forty_two' } assert_equal mock_subfaculty, assigns(:subfaculty) assert_equal mock_speciality, assigns(:speciality) assert_equal mock_group, assigns(:plan_group) assert_equal mock_education, assigns(:education) end protected def should_find_parents Plan::Group.expects(:find_by_slug).with('forty_two').returns(mock_group) mock_group.expects(:speciality).returns(mock_speciality) mock_group.expects(:educations).returns(mock_education) mock_education.expects(:build).returns(mock_education) mock_speciality.expects(:to_param).returns('37') Plan::Group.expects(:find_by_slug).with('forty_two').returns(mock_group) Speciality.expects(:find).with('37').returns(mock_speciality) end def mock_group(stubs={}) @mock_group ||= mock(stubs) end def mock_education(stubs={}) @mock_education ||= mock(stubs) end def mock_speciality(stubs={}) @mock_speciality ||= mock(stubs) end def mock_subfaculty(stubs={}) @mock_subfaculty ||= mock(stubs) end end inherited_resources-1.13.0/test/nested_singleton_test.rb000066400000000000000000000127321404526035200235560ustar00rootroot00000000000000require 'test_helper' # This test file is instead to test the how controller flow and actions # using a belongs_to association. This is done using mocks a la rspec. # class Party extend ActiveModel::Naming end class Venue extend ActiveModel::Naming end class Address extend ActiveModel::Naming end ActiveSupport::Inflector.inflections do |inflect| inflect.singular "address", "address" inflect.plural "address", "addresses" end class VenueController < InheritedResources::Base defaults singleton: true belongs_to :party end # for the slightly pathological # /party/37/venue/address case class AddressController < InheritedResources::Base defaults singleton: true belongs_to :party do belongs_to :venue, singleton: true end end #and the more pathological case class GeolocationController < InheritedResources::Base defaults singleton: true belongs_to :party do belongs_to :venue, singleton: true do belongs_to :address, singleton: true end end end class NestedSingletonTest < ActionController::TestCase tests AddressController def setup draw_routes do resources :party do resource :venue, controller: :venue do resource :address, controller: :address do resource :geolocation, controller: :geolocation end end end end end def teardown clear_routes end def test_does_not_break_parent_controller #this is kind of tacky, but seems to work old_controller = @controller @controller = VenueController.new Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) get :show, params: { party_id: '37' } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) ensure @controller = old_controller end def test_does_not_break_child_controller #this is kind of tacky, but seems to work old_controller = @controller @controller = GeolocationController.new Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) mock_venue.expects(:address).returns(mock_address) mock_address.expects(:geolocation).returns(mock_geolocation) get :show, params: { party_id: '37' } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) assert_equal mock_geolocation, assigns(:geolocation) ensure @controller = old_controller end def test_expose_a_new_address_on_new Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) mock_venue.expects(:build_address).returns(mock_address) get :new, params: { party_id: '37' } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) end def test_expose_the_address_on_edit Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) mock_venue.expects(:address).returns(mock_address) get :edit, params: { party_id: '37' } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) assert_response :success end def test_expose_the_address_on_show Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) mock_venue.expects(:address).returns(mock_address) get :show, params: { party_id: '37' } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) assert_response :success end def test_expose_a_newly_create_address_on_create Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) mock_venue.expects(:build_address).with({'these' => 'params'}).returns(mock_address(save: true)) post :create, params: { party_id: '37', address: {these: 'params'} } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) end def test_update_the_requested_object_on_update Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue(address: mock_address)) mock_address.expects(:update).with({'these' => 'params'}).returns(mock_address(save: true)) post :update, params: { party_id: '37', address: {these: 'params'} } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) end def test_the_requested_manager_is_destroyed_on_destroy Party.expects(:find).with('37').returns(mock_party) mock_party.expects(:venue).returns(mock_venue) mock_venue.expects(:address).returns(mock_address) @controller.expects(:parent_url).returns('http://test.host/') mock_address.expects(:destroy) delete :destroy, params: { party_id: '37' } assert_equal mock_party, assigns(:party) assert_equal mock_venue, assigns(:venue) assert_equal mock_address, assigns(:address) end protected def mock_party(stubs={}) @mock_party ||= mock('party',stubs) end def mock_venue(stubs={}) @mock_venue ||= mock('venue',stubs) end def mock_address(stubs={}) @mock_address ||= mock('address',stubs) end def mock_geolocation(stubs={}) @mock_geolocation ||= mock('geolocation', stubs) end end inherited_resources-1.13.0/test/optional_belongs_to_test.rb000066400000000000000000000134521404526035200242520ustar00rootroot00000000000000require 'test_helper' class Brands; end class Category; end class Product def self.human_name; 'Product'; end end class ProductsController < InheritedResources::Base belongs_to :brand, :category, polymorphic: true, optional: true end class OptionalTest < ActionController::TestCase tests ProductsController def setup draw_routes do resources :products end @controller.stubs(:resource_url).returns('/') end def teardown clear_routes end def test_expose_all_products_as_instance_variable_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:scoped).returns([mock_product]) get :index, params: { category_id: '37' } assert_equal mock_category, assigns(:category) assert_equal [mock_product], assigns(:products) end def test_expose_all_products_as_instance_variable_without_category Product.expects(:scoped).returns([mock_product]) get :index assert_nil assigns(:category) assert_equal [mock_product], assigns(:products) end def test_expose_the_requested_product_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:find).with('42').returns(mock_product) get :show, params: { id: '42', category_id: '37' } assert_equal mock_category, assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_the_requested_product_without_category Product.expects(:find).with('42').returns(mock_product) get :show, params: { id: '42' } assert_nil assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_a_new_product_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:build).returns(mock_product) get :new, params: { category_id: '37' } assert_equal mock_category, assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_a_new_product_without_category Product.expects(:new).returns(mock_product) get :new assert_nil assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_the_requested_product_for_edition_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:find).with('42').returns(mock_product) get :edit, params: { id: '42', category_id: '37' } assert_equal mock_category, assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_the_requested_product_for_edition_without_category Product.expects(:find).with('42').returns(mock_product) get :edit, params: { id: '42' } assert_nil assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_a_newly_create_product_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:build).with({'these' => 'params'}).returns(mock_product(save: true)) post :create, params: { category_id: '37', product: {these: 'params'} } assert_equal mock_category, assigns(:category) assert_equal mock_product, assigns(:product) end def test_expose_a_newly_create_product_without_category Product.expects(:new).with({'these' => 'params'}).returns(mock_product(save: true)) post :create, params: { product: {these: 'params'} } assert_nil assigns(:category) assert_equal mock_product, assigns(:product) end def test_update_the_requested_object_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:find).with('42').returns(mock_product) mock_product.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', category_id: '37', product: {these: 'params'} } assert_equal mock_category, assigns(:category) assert_equal mock_product, assigns(:product) end def test_update_the_requested_object_without_category Product.expects(:find).with('42').returns(mock_product) mock_product.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', product: {these: 'params'} } assert_nil assigns(:category) assert_equal mock_product, assigns(:product) end def test_the_requested_product_is_destroyed_with_category Category.expects(:find).with('37').returns(mock_category) mock_category.expects(:products).returns(Product) Product.expects(:find).with('42').returns(mock_product) mock_product.expects(:destroy).returns(true) @controller.expects(:collection_url).returns('/') delete :destroy, params: { id: '42', category_id: '37' } assert_equal mock_category, assigns(:category) assert_equal mock_product, assigns(:product) end def test_the_requested_product_is_destroyed_without_category Product.expects(:find).with('42').returns(mock_product) mock_product.expects(:destroy).returns(true) @controller.expects(:collection_url).returns('/') delete :destroy, params: { id: '42' } assert_nil assigns(:category) assert_equal mock_product, assigns(:product) end def test_polymorphic_helpers Product.expects(:scoped).returns([mock_product]) get :index assert !@controller.send(:parent?) assert_nil assigns(:parent_type) assert_nil @controller.send(:parent_type) assert_nil @controller.send(:parent_class) assert_nil assigns(:category) assert_nil @controller.send(:parent) end protected def mock_category(stubs={}) @mock_category ||= mock(stubs) end def mock_product(stubs={}) @mock_product ||= mock(stubs) end end inherited_resources-1.13.0/test/polymorphic_test.rb000066400000000000000000000162301404526035200225540ustar00rootroot00000000000000require 'test_helper' class Factory; end class Company; end class User; end class Photo; end class Employee def self.human_name; 'Employee'; end end class EmployeesController < InheritedResources::Base belongs_to :factory, :company, polymorphic: true end class PhotosController < InheritedResources::Base belongs_to :user, :task, polymorphic: true def index parent # Overwrite index end end class PolymorphicFactoriesTest < ActionController::TestCase tests EmployeesController def setup draw_routes do resources :employees end Factory.expects(:find).with('37').returns(mock_factory) mock_factory.expects(:employees).returns(Employee) @controller.stubs(:resource_url).returns('/') @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_expose_all_employees_as_instance_variable_on_index Employee.expects(:scoped).returns([mock_employee]) get :index, params: { factory_id: '37' } assert_equal mock_factory, assigns(:factory) assert_equal [mock_employee], assigns(:employees) end def test_expose_the_requested_employee_on_show Employee.expects(:find).with('42').returns(mock_employee) get :show, params: { id: '42', factory_id: '37' } assert_equal mock_factory, assigns(:factory) assert_equal mock_employee, assigns(:employee) end def test_expose_a_new_employee_on_new Employee.expects(:build).returns(mock_employee) get :new, params: { factory_id: '37' } assert_equal mock_factory, assigns(:factory) assert_equal mock_employee, assigns(:employee) end def test_expose_the_requested_employee_on_edit Employee.expects(:find).with('42').returns(mock_employee) get :edit, params: { id: '42', factory_id: '37' } assert_equal mock_factory, assigns(:factory) assert_equal mock_employee, assigns(:employee) assert_response :success end def test_expose_a_newly_create_employee_on_create Employee.expects(:build).with({'these' => 'params'}).returns(mock_employee(save: true)) post :create, params: { factory_id: '37', employee: {these: 'params'} } assert_equal mock_factory, assigns(:factory) assert_equal mock_employee, assigns(:employee) end def test_update_the_requested_object_on_update Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', factory_id: '37', employee: {these: 'params'} } assert_equal mock_factory, assigns(:factory) assert_equal mock_employee, assigns(:employee) end def test_the_requested_employee_is_destroyed_on_destroy Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:destroy) delete :destroy, params: { id: '42', factory_id: '37' } assert_equal mock_factory, assigns(:factory) assert_equal mock_employee, assigns(:employee) end def test_polymorphic_helpers mock_factory.stubs(:class).returns(Factory) Employee.expects(:scoped).returns([mock_employee]) get :index, params: { factory_id: '37' } assert @controller.send(:parent?) assert_equal :factory, assigns(:parent_type) assert_equal :factory, @controller.send(:parent_type) assert_equal Factory, @controller.send(:parent_class) assert_equal mock_factory, assigns(:factory) assert_equal mock_factory, @controller.send(:parent) end protected def mock_factory(stubs={}) @mock_factory ||= mock(stubs) end def mock_employee(stubs={}) @mock_employee ||= mock(stubs) end end class PolymorphicCompanyTest < ActionController::TestCase tests EmployeesController def setup draw_routes do resources :employees end Company.expects(:find).with('37').returns(mock_company) mock_company.expects(:employees).returns(Employee) @controller.stubs(:resource_url).returns('/') @controller.stubs(:collection_url).returns('/') end def teardown clear_routes end def test_expose_all_employees_as_instance_variable_on_index Employee.expects(:scoped).returns([mock_employee]) get :index, params: { company_id: '37' } assert_equal mock_company, assigns(:company) assert_equal [mock_employee], assigns(:employees) end def test_expose_the_requested_employee_on_show Employee.expects(:find).with('42').returns(mock_employee) get :show, params: { id: '42', company_id: '37' } assert_equal mock_company, assigns(:company) assert_equal mock_employee, assigns(:employee) end def test_expose_a_new_employee_on_new Employee.expects(:build).returns(mock_employee) get :new, params: { company_id: '37' } assert_equal mock_company, assigns(:company) assert_equal mock_employee, assigns(:employee) end def test_expose_the_requested_employee_on_edit Employee.expects(:find).with('42').returns(mock_employee) get :edit, params: { id: '42', company_id: '37' } assert_equal mock_company, assigns(:company) assert_equal mock_employee, assigns(:employee) assert_response :success end def test_expose_a_newly_create_employee_on_create Employee.expects(:build).with({'these' => 'params'}).returns(mock_employee(save: true)) post :create, params: { company_id: '37', employee: {these: 'params'} } assert_equal mock_company, assigns(:company) assert_equal mock_employee, assigns(:employee) end def test_update_the_requested_object_on_update Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { id: '42', company_id: '37', employee: {these: 'params'} } assert_equal mock_company, assigns(:company) assert_equal mock_employee, assigns(:employee) end def test_the_requested_employee_is_destroyed_on_destroy Employee.expects(:find).with('42').returns(mock_employee) mock_employee.expects(:destroy) delete :destroy, params: { id: '42', company_id: '37' } assert_equal mock_company, assigns(:company) assert_equal mock_employee, assigns(:employee) end def test_polymorphic_helpers mock_company.stubs(:class).returns(Company) Employee.expects(:scoped).returns([mock_employee]) get :index, params: { company_id: '37' } assert @controller.send(:parent?) assert_equal :company, assigns(:parent_type) assert_equal :company, @controller.send(:parent_type) assert_equal Company, @controller.send(:parent_class) assert_equal mock_company, assigns(:company) assert_equal mock_company, @controller.send(:parent) end protected def mock_company(stubs={}) @mock_company ||= mock(stubs) end def mock_employee(stubs={}) @mock_employee ||= mock(stubs) end end class PolymorphicPhotosTest < ActionController::TestCase tests PhotosController def setup draw_routes do resources :photos end User.expects(:find).with('37').returns(mock_user) end def teardown clear_routes end def test_parent_as_instance_variable_on_index_when_method_overwritten get :index, params: { user_id: '37' } assert_equal mock_user, assigns(:user) end protected def mock_user(stubs={}) @mock_user ||= mock(stubs) end end inherited_resources-1.13.0/test/rails_52/000077500000000000000000000000001404526035200202415ustar00rootroot00000000000000inherited_resources-1.13.0/test/rails_52/Gemfile000066400000000000000000000003011404526035200215260ustar00rootroot00000000000000source 'https://rubygems.org' gemspec path: '../..' group :development do gem 'rails', '~> 5.2.6.a' gem 'mocha' gem 'minitest-rg' gem 'rails-controller-testing' gem 'chandler' end inherited_resources-1.13.0/test/rails_52/Gemfile.lock000066400000000000000000000100341404526035200224610ustar00rootroot00000000000000PATH remote: ../.. specs: inherited_resources (1.13.0) actionpack (>= 5.2, < 6.2) has_scope (~> 0.6) railties (>= 5.2, < 6.2) responders (>= 2, < 4) GEM remote: https://rubygems.org/ specs: actioncable (5.2.6) actionpack (= 5.2.6) nio4r (~> 2.0) websocket-driver (>= 0.6.1) actionmailer (5.2.6) actionpack (= 5.2.6) actionview (= 5.2.6) activejob (= 5.2.6) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) actionpack (5.2.6) actionview (= 5.2.6) activesupport (= 5.2.6) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) actionview (5.2.6) activesupport (= 5.2.6) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) activejob (5.2.6) activesupport (= 5.2.6) globalid (>= 0.3.6) activemodel (5.2.6) activesupport (= 5.2.6) activerecord (5.2.6) activemodel (= 5.2.6) activesupport (= 5.2.6) arel (>= 9.0) activestorage (5.2.6) actionpack (= 5.2.6) activerecord (= 5.2.6) marcel (~> 1.0.0) activesupport (5.2.6) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) arel (9.0.0) builder (3.2.4) chandler (0.9.0) netrc octokit (>= 2.2.0) concurrent-ruby (1.1.8) crass (1.0.6) erubi (1.10.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) globalid (0.4.2) activesupport (>= 4.2.0) has_scope (0.8.0) actionpack (>= 5.2) activesupport (>= 5.2) i18n (1.8.10) concurrent-ruby (~> 1.0) loofah (2.9.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.1) method_source (1.0.0) mini_mime (1.1.0) mini_portile2 (2.5.1) minitest (5.14.4) minitest-rg (5.2.0) minitest (~> 5.0) mocha (1.12.0) multipart-post (2.1.1) netrc (0.11.0) nio4r (2.5.7) nio4r (2.5.7-java) nokogiri (1.11.3) mini_portile2 (~> 2.5.0) racc (~> 1.4) nokogiri (1.11.3-java) racc (~> 1.4) octokit (4.18.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) public_suffix (4.0.5) racc (1.5.2) racc (1.5.2-java) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) rails (5.2.6) actioncable (= 5.2.6) actionmailer (= 5.2.6) actionpack (= 5.2.6) actionview (= 5.2.6) activejob (= 5.2.6) activemodel (= 5.2.6) activerecord (= 5.2.6) activestorage (= 5.2.6) activesupport (= 5.2.6) bundler (>= 1.3.0) railties (= 5.2.6) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) railties (5.2.6) actionpack (= 5.2.6) activesupport (= 5.2.6) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) rake (13.0.3) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) thor (1.1.0) thread_safe (0.3.6) thread_safe (0.3.6-java) tzinfo (1.2.9) thread_safe (~> 0.1) websocket-driver (0.7.3) websocket-extensions (>= 0.1.0) websocket-driver (0.7.3-java) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) PLATFORMS java ruby DEPENDENCIES chandler inherited_resources! minitest-rg mocha rails (~> 5.2.6.a) rails-controller-testing BUNDLED WITH 2.2.17 inherited_resources-1.13.0/test/rails_60/000077500000000000000000000000001404526035200202405ustar00rootroot00000000000000inherited_resources-1.13.0/test/rails_60/Gemfile000066400000000000000000000003011404526035200215250ustar00rootroot00000000000000source 'https://rubygems.org' gemspec path: '../..' group :development do gem 'rails', '~> 6.0.3.a' gem 'mocha' gem 'minitest-rg' gem 'rails-controller-testing' gem 'chandler' end inherited_resources-1.13.0/test/rails_60/Gemfile.lock000066400000000000000000000115121404526035200224620ustar00rootroot00000000000000PATH remote: ../.. specs: inherited_resources (1.13.0) actionpack (>= 5.2, < 6.2) has_scope (~> 0.6) railties (>= 5.2, < 6.2) responders (>= 2, < 4) GEM remote: https://rubygems.org/ specs: actioncable (6.0.3.7) actionpack (= 6.0.3.7) nio4r (~> 2.0) websocket-driver (>= 0.6.1) actionmailbox (6.0.3.7) actionpack (= 6.0.3.7) activejob (= 6.0.3.7) activerecord (= 6.0.3.7) activestorage (= 6.0.3.7) activesupport (= 6.0.3.7) mail (>= 2.7.1) actionmailer (6.0.3.7) actionpack (= 6.0.3.7) actionview (= 6.0.3.7) activejob (= 6.0.3.7) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) actionpack (6.0.3.7) actionview (= 6.0.3.7) activesupport (= 6.0.3.7) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) actiontext (6.0.3.7) actionpack (= 6.0.3.7) activerecord (= 6.0.3.7) activestorage (= 6.0.3.7) activesupport (= 6.0.3.7) nokogiri (>= 1.8.5) actionview (6.0.3.7) activesupport (= 6.0.3.7) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) activejob (6.0.3.7) activesupport (= 6.0.3.7) globalid (>= 0.3.6) activemodel (6.0.3.7) activesupport (= 6.0.3.7) activerecord (6.0.3.7) activemodel (= 6.0.3.7) activesupport (= 6.0.3.7) activestorage (6.0.3.7) actionpack (= 6.0.3.7) activejob (= 6.0.3.7) activerecord (= 6.0.3.7) marcel (~> 1.0.0) activesupport (6.0.3.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2, >= 2.2.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) builder (3.2.4) chandler (0.9.0) netrc octokit (>= 2.2.0) concurrent-ruby (1.1.8) crass (1.0.6) erubi (1.10.0) faraday (1.4.1) faraday-excon (~> 1.1) faraday-net_http (~> 1.0) faraday-net_http_persistent (~> 1.1) multipart-post (>= 1.2, < 3) ruby2_keywords (>= 0.0.4) faraday-excon (1.1.0) faraday-net_http (1.0.1) faraday-net_http_persistent (1.1.0) globalid (0.4.2) activesupport (>= 4.2.0) has_scope (0.8.0) actionpack (>= 5.2) activesupport (>= 5.2) i18n (1.8.10) concurrent-ruby (~> 1.0) loofah (2.9.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.1) method_source (1.0.0) mini_mime (1.1.0) mini_portile2 (2.5.1) minitest (5.14.4) minitest-rg (5.2.0) minitest (~> 5.0) mocha (1.12.0) multipart-post (2.1.1) netrc (0.11.0) nio4r (2.5.7) nio4r (2.5.7-java) nokogiri (1.11.3) mini_portile2 (~> 2.5.0) racc (~> 1.4) nokogiri (1.11.3-java) racc (~> 1.4) octokit (4.21.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) public_suffix (4.0.6) racc (1.5.2) racc (1.5.2-java) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) rails (6.0.3.7) actioncable (= 6.0.3.7) actionmailbox (= 6.0.3.7) actionmailer (= 6.0.3.7) actionpack (= 6.0.3.7) actiontext (= 6.0.3.7) actionview (= 6.0.3.7) activejob (= 6.0.3.7) activemodel (= 6.0.3.7) activerecord (= 6.0.3.7) activestorage (= 6.0.3.7) activesupport (= 6.0.3.7) bundler (>= 1.3.0) railties (= 6.0.3.7) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) railties (6.0.3.7) actionpack (= 6.0.3.7) activesupport (= 6.0.3.7) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) rake (13.0.3) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) ruby2_keywords (0.0.4) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) thor (1.1.0) thread_safe (0.3.6) thread_safe (0.3.6-java) tzinfo (1.2.9) thread_safe (~> 0.1) websocket-driver (0.7.3) websocket-extensions (>= 0.1.0) websocket-driver (0.7.3-java) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) zeitwerk (2.4.2) PLATFORMS java ruby DEPENDENCIES chandler inherited_resources! minitest-rg mocha rails (~> 6.0.3.a) rails-controller-testing BUNDLED WITH 2.2.17 inherited_resources-1.13.0/test/redirect_to_test.rb000066400000000000000000000024621404526035200225140ustar00rootroot00000000000000require 'test_helper' class Machine; def self.human_name; 'Machine'; end end class MachinesController < InheritedResources::Base def create create!{ complex_url(:create, true, true) } end def update update!{ complex_url(:update, false, false) } end def destroy destroy!{ complex_url(:destroy, true, false) } end protected def complex_url(name, arg2, arg3) 'http://test.host/' + name.to_s end end class RedirectToWithBlockTest < ActionController::TestCase tests MachinesController def setup draw_routes do resources :machines end end def teardown clear_routes end def test_redirect_to_the_given_url_on_create Machine.stubs(:new).returns(mock_machine(save: true)) post :create assert_redirected_to 'http://test.host/create' end def test_redirect_to_the_given_url_on_update Machine.stubs(:find).returns(mock_machine(update: true)) put :update, params: { id: '42' } assert_redirected_to 'http://test.host/update' end def test_redirect_to_the_given_url_on_destroy Machine.stubs(:find).returns(mock_machine(destroy: true)) delete :destroy, params: { id: '42' } assert_redirected_to 'http://test.host/destroy' end protected def mock_machine(stubs={}) @mock_machine ||= mock(stubs) end end inherited_resources-1.13.0/test/singleton_test.rb000066400000000000000000000054561404526035200222210ustar00rootroot00000000000000require 'test_helper' # This test file is instead to test the how controller flow and actions # using a belongs_to association. This is done using mocks a la rspec. # class Store extend ActiveModel::Naming end class Manager extend ActiveModel::Naming end class ManagersController < InheritedResources::Base defaults singleton: true belongs_to :store end class SingletonTest < ActionController::TestCase tests ManagersController def setup draw_routes do resources :store do resource :manager end end end def teardown clear_routes end def test_expose_the_requested_manager_on_show Store.expects(:find).with('37').returns(mock_store) mock_store.expects(:manager).returns(mock_manager) get :show, params: { store_id: '37' } assert_equal mock_store, assigns(:store) assert_equal mock_manager, assigns(:manager) end def test_expose_a_new_manager_on_new Store.expects(:find).with('37').returns(mock_store) mock_store.expects(:build_manager).returns(mock_manager) get :new, params: { store_id: '37' } assert_equal mock_store, assigns(:store) assert_equal mock_manager, assigns(:manager) end def test_expose_the_requested_manager_on_edit Store.expects(:find).with('37').returns(mock_store) mock_store.expects(:manager).returns(mock_manager) get :edit, params: { store_id: '37' } assert_equal mock_store, assigns(:store) assert_equal mock_manager, assigns(:manager) assert_response :success end def test_expose_a_newly_create_manager_on_create Store.expects(:find).with('37').returns(mock_store) mock_store.expects(:build_manager).with({'these' => 'params'}).returns(mock_manager(save: true)) post :create, params: { store_id: '37', manager: {these: 'params'} } assert_equal mock_store, assigns(:store) assert_equal mock_manager, assigns(:manager) end def test_update_the_requested_object_on_update Store.expects(:find).with('37').returns(mock_store(manager: mock_manager)) mock_manager.expects(:update).with({'these' => 'params'}).returns(true) put :update, params: { store_id: '37', manager: {these: 'params'} } assert_equal mock_store, assigns(:store) assert_equal mock_manager, assigns(:manager) end def test_the_requested_manager_is_destroyed_on_destroy Store.expects(:find).with('37').returns(mock_store) mock_store.expects(:manager).returns(mock_manager) @controller.expects(:parent_url).returns('http://test.host/') mock_manager.expects(:destroy) delete :destroy, params: { store_id: '37' } assert_equal mock_store, assigns(:store) assert_equal mock_manager, assigns(:manager) end protected def mock_store(stubs={}) @mock_store ||= mock(stubs) end def mock_manager(stubs={}) @mock_manager ||= mock(stubs) end end inherited_resources-1.13.0/test/strong_parameters_test.rb000066400000000000000000000110471404526035200237470ustar00rootroot00000000000000require 'test_helper' class Widget extend ActiveModel::Naming include ActiveModel::Conversion end class WidgetsController < InheritedResources::Base end # test usage of `permitted_params` class StrongParametersTest < ActionController::TestCase def setup draw_routes do resources :widgets end @controller = WidgetsController.new @controller.stubs(:widget_url).returns("/") @controller.stubs(:permitted_params).returns(widget: {permitted: 'param'}) class << @controller private :permitted_params end end def teardown clear_routes end def test_permitted_params_from_new Widget.expects(:new).with(permitted: 'param') get :new, params: { widget: { permitted: 'param', prohibited: 'param' } } end def test_permitted_params_from_create Widget.expects(:new).with(permitted: 'param').returns(mock(save: true)) post :create, params: { widget: { permitted: 'param', prohibited: 'param' } } end def test_permitted_params_from_update mock_widget = mock mock_widget.stubs(:class).returns(Widget) mock_widget.expects(:update).with(permitted: 'param') mock_widget.stubs(:persisted?).returns(true) mock_widget.stubs(:to_model).returns(mock_widget) mock_widget.stubs(:model_name).returns(Widget.model_name) Widget.expects(:find).with('42').returns(mock_widget) put :update, params: { id: '42', widget: {permitted: 'param', prohibited: 'param'} } end # `permitted_params` has greater priority than `widget_params` def test_with_permitted_and_resource_methods @controller.stubs(:widget_params).returns(permitted: 'another_param') class << @controller private :widget_params end Widget.expects(:new).with(permitted: 'param') get :new, params: { widget: { permitted: 'param', prohibited: 'param' } } end end # test usage of `widget_params` class StrongParametersWithoutPermittedParamsTest < ActionController::TestCase def setup draw_routes do resources :widgets end @controller = WidgetsController.new @controller.stubs(:widget_url).returns("/") @controller.stubs(:widget_params).returns(permitted: 'param') class << @controller private :widget_params end end def teardown clear_routes end def test_permitted_params_from_new Widget.expects(:new).with(permitted: 'param') get :new, params: { widget: { permitted: 'param', prohibited: 'param' } } end def test_permitted_params_from_create Widget.expects(:new).with(permitted: 'param').returns(mock(save: true)) post :create, params: { widget: { permitted: 'param', prohibited: 'param' } } end def test_permitted_params_from_update mock_widget = mock mock_widget.stubs(:class).returns(Widget) mock_widget.expects(:update).with(permitted: 'param') mock_widget.stubs(:persisted?).returns(true) mock_widget.stubs(:to_model).returns(mock_widget) mock_widget.stubs(:model_name).returns(Widget.model_name) Widget.expects(:find).with('42').returns(mock_widget) put :update, params: { id: '42', widget: {permitted: 'param', prohibited: 'param'} } end end # test usage of `widget_params` integrated with strong parameters (not using stubs) class StrongParametersIntegrationTest < ActionController::TestCase def setup draw_routes do resources :widgets end @controller = WidgetsController.new @controller.stubs(:widget_url).returns("/") class << @controller define_method :widget_params do params.require(:widget).permit(:permitted) end private :widget_params end end def teardown clear_routes end def test_permitted_empty_params_from_new Widget.expects(:new).with({}) get :new, params: {} end def test_permitted_params_from_new Widget.expects(:new).with('permitted' => 'param') get :new, params: { widget: { permitted: 'param', prohibited: 'param' } } end def test_permitted_params_from_create Widget.expects(:new).with('permitted' => 'param').returns(mock(save: true)) post :create, params: { widget: { permitted: 'param', prohibited: 'param' } } end def test_permitted_params_from_update mock_widget = mock mock_widget.stubs(:class).returns(Widget) mock_widget.expects(:update).with('permitted' => 'param') mock_widget.stubs(:persisted?).returns(true) mock_widget.stubs(:to_model).returns(mock_widget) mock_widget.stubs(:model_name).returns(Widget.model_name) Widget.expects(:find).with('42').returns(mock_widget) put :update, params: { id: '42', widget: {permitted: 'param', prohibited: 'param'} } end end inherited_resources-1.13.0/test/test_helper.rb000066400000000000000000000022621404526035200214660ustar00rootroot00000000000000require 'rubygems' require 'bundler' Bundler.setup require 'minitest/autorun' require 'mocha/minitest' require 'minitest/rg' ENV["RAILS_ENV"] = "test" RAILS_ROOT = "anywhere" require "active_support" require "active_model" require "action_controller" require 'rails-controller-testing' Rails::Controller::Testing.install I18n.load_path << File.join(File.dirname(__FILE__), 'locales', 'en.yml') I18n.reload! class ApplicationController < ActionController::Base; end # Add IR to load path and load the main file $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'inherited_resources' ActionController::Base.view_paths = File.join(File.dirname(__FILE__), 'views') InheritedResources::Routes = ActionDispatch::Routing::RouteSet.new def draw_routes(&block) InheritedResources::Routes.draw(&block) end def clear_routes InheritedResources::Routes.draw { } end ActionController::Base.send :include, InheritedResources::Routes.url_helpers # Add app base to load path $:.unshift File.expand_path(File.dirname(__FILE__) + '/../app/controllers') require 'inherited_resources/base' class ActiveSupport::TestCase setup do @routes = InheritedResources::Routes end end inherited_resources-1.13.0/test/url_helpers_test.rb000066400000000000000000001044441404526035200225400ustar00rootroot00000000000000require 'test_helper' class ModelBase extend ActiveModel::Naming include ActiveModel::Conversion end class Universe < ModelBase end class UniversesController < InheritedResources::Base defaults singleton: true, route_instance_name: 'universum' end class House < ModelBase end class HousesController < InheritedResources::Base end class News < ModelBase end class NewsController < InheritedResources::Base end class Backpack < ModelBase end module Admin; end class Admin::BackpacksController < InheritedResources::Base defaults route_collection_name: 'tour_backpacks' end class Table < ModelBase end class TablesController < InheritedResources::Base belongs_to :house end class RoomsController < InheritedResources::Base belongs_to :house, route_name: 'big_house' end class ChairsController < InheritedResources::Base belongs_to :house do belongs_to :table end end class OwnersController < InheritedResources::Base defaults singleton: true belongs_to :house end class Fireplace extend ActiveModel::Naming end class Flame extend ActiveModel::Naming end class FlamesController < InheritedResources::Base belongs_to :house do belongs_to :fireplace, singleton: true end end class Bed extend ActiveModel::Naming include ActiveModel::Conversion end class BedsController < InheritedResources::Base optional_belongs_to :house, :building end class Sheep < ModelBase end class SheepController < InheritedResources::Base belongs_to :news, :table, polymorphic: true end class Fish < ModelBase end class FishController < InheritedResources::Base belongs_to :bed, shallow: true end class Desk < ModelBase end module Admin class DesksController < InheritedResources::Base optional_belongs_to :house end end class Dish < ModelBase end class DishesController < InheritedResources::Base belongs_to :house do polymorphic_belongs_to :table, :kitchen end end class Dishwasher < ModelBase end class Fork < ModelBase end class Spot < ModelBase end class SpotsController < InheritedResources::Base belongs_to :house do belongs_to :dishwasher, singleton: true do polymorphic_belongs_to :dish, :fork end end end class Center extend ActiveModel::Naming end class CentersController < InheritedResources::Base acts_as_singleton! belongs_to :house do belongs_to :table, :kitchen, polymorphic: true end end class Mirror extend ActiveModel::Naming end class MirrorsController < InheritedResources::Base belongs_to :house, shallow: true end class Admin::MirrorsController < InheritedResources::Base belongs_to :house, shallow: true end class Display extend ActiveModel::Naming end class Window extend ActiveModel::Naming end class Button extend ActiveModel::Naming end class ButtonsController < InheritedResources::Base belongs_to :display, :window, shallow: true custom_actions resource: :delete, collection: :search end class ImageButtonsController < ButtonsController end # Create a TestHelper module with some helpers class UrlHelpersTest < ActiveSupport::TestCase def mock_polymorphic(controller, route) controller.expects(route) end def test_url_helpers_on_simple_inherited_resource controller = HousesController.new controller.instance_variable_set('@house', :house) [:url, :path].each do |path_or_url| controller.expects("houses_#{path_or_url}").with({}).once controller.send("collection_#{path_or_url}") controller.expects("house_#{path_or_url}").with(:house, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_house_#{path_or_url}").with({}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_house_#{path_or_url}").with(:house, {}).once controller.send("edit_resource_#{path_or_url}") # With arg controller.expects("house_#{path_or_url}").with(:arg, {}).once controller.send("resource_#{path_or_url}", :arg) controller.expects("house_#{path_or_url}").with(:arg, {}).once controller.send("resource_#{path_or_url}", :arg) # With options controller.expects("house_#{path_or_url}").with(:arg, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_simple_inherited_resource_using_uncountable controller = NewsController.new controller.instance_variable_set('@news', :news) [:url, :path].each do |path_or_url| controller.expects("news_index_#{path_or_url}").with({}).once controller.send("collection_#{path_or_url}") controller.expects("news_#{path_or_url}").with(:news, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_news_#{path_or_url}").with({}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_news_#{path_or_url}").with(:news, {}).once controller.send("edit_resource_#{path_or_url}") # With arg controller.expects("news_#{path_or_url}").with(:arg, {}).once controller.send("resource_#{path_or_url}", :arg) controller.expects("news_#{path_or_url}").with(:arg, {}).once controller.send("resource_#{path_or_url}", :arg) # With options controller.expects("news_#{path_or_url}").with(:arg, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_simple_inherited_namespaced_resource controller = Admin::BackpacksController.new controller.instance_variable_set('@backpack', :backpack) assert_equal :admin, controller.class.resources_configuration[:self][:route_prefix] [:url, :path].each do |path_or_url| controller.expects("admin_tour_backpacks_#{path_or_url}").with({}).once controller.send("collection_#{path_or_url}") controller.expects("admin_backpack_#{path_or_url}").with(:backpack, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_admin_backpack_#{path_or_url}").with({}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_admin_backpack_#{path_or_url}").with(:backpack, {}).once controller.send("edit_resource_#{path_or_url}") # With arg controller.expects("admin_backpack_#{path_or_url}").with(:arg, {}).once controller.send("resource_#{path_or_url}", :arg) controller.expects("admin_backpack_#{path_or_url}").with(:arg, {}).once controller.send("resource_#{path_or_url}", :arg) # With options controller.expects("admin_backpack_#{path_or_url}").with(:arg, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_simple_inherited_singleton_resource controller = UniversesController.new controller.instance_variable_set('@universe', :universe) [:url, :path].each do |path_or_url| controller.expects("root_#{path_or_url}").with({}).once controller.send("collection_#{path_or_url}") controller.expects("universum_#{path_or_url}").with({}).once controller.send("resource_#{path_or_url}") controller.expects("new_universum_#{path_or_url}").with({}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_universum_#{path_or_url}").with({}).once controller.send("edit_resource_#{path_or_url}") # With options # Also tests that argument sent are not used controller.expects("universum_#{path_or_url}").with(page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_singleton_belongs_to controller = FlamesController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@fireplace', :fireplace) controller.instance_variable_set('@flame', :flame) [:url, :path].each do |path_or_url| controller.expects("house_fireplace_flames_#{path_or_url}").with(:house, {}).once controller.send("collection_#{path_or_url}") controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_house_fireplace_flame_#{path_or_url}").with(:house, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("house_fireplace_#{path_or_url}").with(:house, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_house_fireplace_#{path_or_url}").with(:house, {}).once controller.send("edit_parent_#{path_or_url}") # With options # Also tests that argument sent are not used controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :arg, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_belongs_to controller = TablesController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@table', :table) [:url, :path].each do |path_or_url| controller.expects("house_tables_#{path_or_url}").with(:house, {}).once controller.send("collection_#{path_or_url}") controller.expects("house_table_#{path_or_url}").with(:house, :table, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_house_table_#{path_or_url}").with(:house, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_house_table_#{path_or_url}").with(:house, :table, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("house_#{path_or_url}").with(:house, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_house_#{path_or_url}").with(:house, {}).once controller.send("edit_parent_#{path_or_url}") # With arg controller.expects("house_table_#{path_or_url}").with(:house, :arg, {}).once controller.send("resource_#{path_or_url}", :arg) controller.expects("edit_house_table_#{path_or_url}").with(:house, :arg, {}).once controller.send("edit_resource_#{path_or_url}", :arg) controller.expects("house_#{path_or_url}").with(:arg, {}).once controller.send("parent_#{path_or_url}", :arg) # With options controller.expects("house_table_#{path_or_url}").with(:house, :arg, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_not_default_belongs_to controller = RoomsController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@room', :room) [:url, :path].each do |path_or_url| controller.expects("big_house_rooms_#{path_or_url}").with(:house, {}).once controller.send("collection_#{path_or_url}") controller.expects("big_house_room_#{path_or_url}").with(:house, :room, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_big_house_room_#{path_or_url}").with(:house, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_big_house_room_#{path_or_url}").with(:house, :room, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("big_house_#{path_or_url}").with(:house, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_big_house_#{path_or_url}").with(:house, {}).once controller.send("edit_parent_#{path_or_url}") # With args controller.expects("big_house_room_#{path_or_url}").with(:house, :arg, {}).once controller.send("resource_#{path_or_url}", :arg) controller.expects("edit_big_house_room_#{path_or_url}").with(:house, :arg, {}).once controller.send("edit_resource_#{path_or_url}", :arg) controller.expects("big_house_#{path_or_url}").with(:arg, {}).once controller.send("parent_#{path_or_url}", :arg) # With options controller.expects("big_house_room_#{path_or_url}").with(:house, :arg, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_nested_belongs_to controller = ChairsController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@table', :table) controller.instance_variable_set('@chair', :chair) [:url, :path].each do |path_or_url| controller.expects("house_table_chairs_#{path_or_url}").with(:house, :table, {}).once controller.send("collection_#{path_or_url}") controller.expects("house_table_chair_#{path_or_url}").with(:house, :table, :chair, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_house_table_chair_#{path_or_url}").with(:house, :table, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_house_table_chair_#{path_or_url}").with(:house, :table, :chair, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("house_table_#{path_or_url}").with(:house, :table, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_house_table_#{path_or_url}").with(:house, :table, {}).once controller.send("edit_parent_#{path_or_url}") # With args controller.expects("edit_house_table_chair_#{path_or_url}").with(:house, :table, :arg, {}).once controller.send("edit_resource_#{path_or_url}", :arg) controller.expects("house_table_chair_#{path_or_url}").with(:house, :table, :arg, {}).once controller.send("resource_#{path_or_url}", :arg) controller.expects("house_table_#{path_or_url}").with(:house, :arg, {}).once controller.send("parent_#{path_or_url}", :arg) # With options controller.expects("edit_house_table_chair_#{path_or_url}").with(:house, :table, :arg, page: 1).once controller.send("edit_resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_singletons_with_belongs_to controller = OwnersController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@owner', :owner) [:url, :path].each do |path_or_url| controller.expects("house_#{path_or_url}").with(:house, {}).once controller.send("collection_#{path_or_url}") controller.expects("house_owner_#{path_or_url}").with(:house, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_house_owner_#{path_or_url}").with(:house, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_house_owner_#{path_or_url}").with(:house, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("house_#{path_or_url}").with(:house, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_house_#{path_or_url}").with(:house, {}).once controller.send("edit_parent_#{path_or_url}") # With options # Also tests that argument sent are not used controller.expects("house_owner_#{path_or_url}").with(:house, page: 1).once controller.send("resource_#{path_or_url}", :arg, page: 1) end end def test_url_helpers_on_singleton_and_polymorphic_belongs_to house = House.new dishwasher = Dishwasher.new fork = Fork.new fork.stubs(:persisted?).returns(true) spot = Spot.new spot.stubs(:persisted?).returns(true) new_spot = Spot.new Spot.stubs(:new).returns(new_spot) new_spot.stubs(:persisted?).returns(false) controller = SpotsController.new controller.instance_variable_set('@parent_type', :fork) controller.instance_variable_set('@house', house) controller.instance_variable_set('@dishwasher', dishwasher) controller.instance_variable_set('@fork', fork) controller.instance_variable_set('@spot', spot) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "house_dishwasher_fork_spots_#{path_or_url}").with(house, fork).once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork).once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once controller.send("edit_resource_#{path_or_url}") mock_polymorphic(controller, "house_dishwasher_fork_#{path_or_url}").with(house, fork).once controller.send("parent_#{path_or_url}") mock_polymorphic(controller, "edit_house_dishwasher_fork_#{path_or_url}").with(house, fork).once controller.send("edit_parent_#{path_or_url}") end end def test_url_helpers_on_polymorphic_belongs_to house = House.new house.stubs(:persisted?).returns(true) bed = Bed.new bed.stubs(:persisted?).returns(true) new_bed = Bed.new Bed.stubs(:new).returns(new_bed) new_bed.stubs(:persisted?).returns(false) controller = BedsController.new controller.instance_variable_set('@parent_type', :house) controller.instance_variable_set('@house', house) controller.instance_variable_set('@bed', bed) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "house_beds_#{path_or_url}").with(house).once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "house_bed_#{path_or_url}").with(house, bed).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_house_bed_#{path_or_url}").with(house).once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_house_bed_#{path_or_url}").with(house, bed).once controller.send("edit_resource_#{path_or_url}") mock_polymorphic(controller, "house_#{path_or_url}").with(house).once controller.send("parent_#{path_or_url}") mock_polymorphic(controller, "edit_house_#{path_or_url}").with(house).once controller.send("edit_parent_#{path_or_url}") end # With options mock_polymorphic(controller, "house_bed_url").with(house, bed, page: 1).once controller.send("resource_url", page: 1) mock_polymorphic(controller, "house_url").with(house, page: 1).once controller.send("parent_url", page: 1) # With args controller.expects("polymorphic_url").with([:arg, new_bed], {}).once controller.send("collection_url", :arg) controller.expects("polymorphic_url").with([house, :arg], {}).once controller.send("resource_url", :arg) controller.expects("edit_polymorphic_url").with([house, :arg], {}).once controller.send("edit_resource_url", :arg) controller.expects("polymorphic_url").with([:arg], {}).once controller.send("parent_url", :arg) end def test_url_helpers_on_polymorphic_belongs_to_using_uncountable sheep = Sheep.new sheep.stubs(:persisted?).returns(true) news = News.new news.stubs(:persisted?).returns(true) new_sheep = Sheep.new Sheep.stubs(:new).returns(new_sheep) new_sheep.stubs(:persisted?).returns(false) controller = SheepController.new controller.instance_variable_set('@parent_type', :news) controller.instance_variable_set('@news', news) controller.instance_variable_set('@sheep', sheep) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "news_sheep_index_#{path_or_url}").with(news).once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "news_sheep_#{path_or_url}").with(news, sheep).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_news_sheep_#{path_or_url}").with(news).once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_news_sheep_#{path_or_url}").with(news, sheep).once controller.send("edit_resource_#{path_or_url}") mock_polymorphic(controller, "news_#{path_or_url}").with(news).once controller.send("parent_#{path_or_url}") mock_polymorphic(controller, "edit_news_#{path_or_url}").with(news).once controller.send("edit_parent_#{path_or_url}") end # With options mock_polymorphic(controller, "news_sheep_url").with(news, sheep, page: 1).once controller.send("resource_url", page: 1) mock_polymorphic(controller, "news_url").with(news, page: 1).once controller.send("parent_url", page: 1) # With args controller.expects("polymorphic_url").with([:arg, new_sheep], {}).once controller.send("collection_url", :arg) controller.expects("polymorphic_url").with([news, :arg], {}).once controller.send("resource_url", :arg) controller.expects("edit_polymorphic_url").with([news, :arg], {}).once controller.send("edit_resource_url", :arg) controller.expects("polymorphic_url").with([:arg], {}).once controller.send("parent_url", :arg) end def test_url_helpers_on_shallow_belongs_to_using_uncountable fish = Fish.new bed = Bed.new new_fish = Fish.new new_fish.stubs(:persisted?).returns(false) Sheep.stubs(:new).returns(new_fish) controller = FishController.new controller.instance_variable_set('@bed', bed) controller.instance_variable_set('@fish', fish) [:url, :path].each do |path_or_url| controller.expects("bed_fish_index_#{path_or_url}").with(bed, {}).once controller.send("collection_#{path_or_url}") controller.expects("fish_#{path_or_url}").with(fish, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_bed_fish_#{path_or_url}").with(bed, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_fish_#{path_or_url}").with(fish, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("bed_#{path_or_url}").with(bed, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_bed_#{path_or_url}").with(bed, {}).once controller.send("edit_parent_#{path_or_url}") end end def test_url_helpers_on_namespaced_polymorphic_belongs_to house = House.new house.stubs(:persisted?).returns(true) desk = Desk.new desk.stubs(:persisted?).returns(true) new_desk = Desk.new Desk.stubs(:new).returns(new_desk) new_desk.stubs(:persisted?).returns(false) controller = Admin::DesksController.new controller.instance_variable_set('@parent_type', :house) controller.instance_variable_set('@house', house) controller.instance_variable_set('@desk', desk) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "admin_house_desks_#{path_or_url}").with(house).once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "admin_house_desk_#{path_or_url}").with(house, desk).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_admin_house_desk_#{path_or_url}").with(house).once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_admin_house_desk_#{path_or_url}").with(house, desk).once controller.send("edit_resource_#{path_or_url}") mock_polymorphic(controller, "admin_house_#{path_or_url}").with(house).once controller.send("parent_#{path_or_url}") mock_polymorphic(controller, "edit_admin_house_#{path_or_url}").with(house).once controller.send("edit_parent_#{path_or_url}") end # With options mock_polymorphic(controller, "admin_house_desk_url").with(house, desk, page: 1).once controller.send("resource_url", page: 1) mock_polymorphic(controller, "admin_house_url").with(house, page: 1).once controller.send("parent_url", page: 1) # With args controller.expects("polymorphic_url").with([:admin, :arg, new_desk], {}).once controller.send("collection_url", :arg) controller.expects("polymorphic_url").with([:admin, house, :arg], {}).once controller.send("resource_url", :arg) controller.expects("edit_polymorphic_url").with([:admin, house, :arg], {}).once controller.send("edit_resource_url", :arg) controller.expects("polymorphic_url").with([:admin, :arg], {}).once controller.send("parent_url", :arg) end def test_url_helpers_on_nested_polymorphic_belongs_to house = House.new table = Table.new table.stubs(:persisted?).returns(true) dish = Dish.new dish.stubs(:persisted?).returns(true) new_dish = Dish.new Dish.stubs(:new).returns(new_dish) new_dish.stubs(:persisted?).returns(false) controller = DishesController.new controller.instance_variable_set('@parent_type', :table) controller.instance_variable_set('@house', house) controller.instance_variable_set('@table', table) controller.instance_variable_set('@dish', dish) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "house_table_dishes_#{path_or_url}").with(house, table).once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "house_table_dish_#{path_or_url}").with(house, table, dish).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_house_table_dish_#{path_or_url}").with(house, table).once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_house_table_dish_#{path_or_url}").with(house, table, dish).once controller.send("edit_resource_#{path_or_url}") mock_polymorphic(controller, "house_table_#{path_or_url}").with(house, table).once controller.send("parent_#{path_or_url}") mock_polymorphic(controller, "edit_house_table_#{path_or_url}").with(house, table).once controller.send("edit_parent_#{path_or_url}") end # With options mock_polymorphic(controller, "house_table_dish_url").with(house, table, dish, page: 1).once controller.send("resource_url", page: 1) mock_polymorphic(controller, "house_table_url").with(house, table, page: 1).once controller.send("parent_url", page: 1) # With args controller.expects("polymorphic_url").with([house, table, :arg], {}).once controller.send("resource_url", :arg) controller.expects("edit_polymorphic_url").with([house, table, :arg], {}).once controller.send("edit_resource_url", :arg) controller.expects("polymorphic_url").with([house, :arg], {}).once controller.send("parent_url", :arg) end def test_url_helpers_on_singleton_nested_polymorphic_belongs_to # This must not be usefull in singleton controllers... # Center.new house = House.new house.stubs(:persisted?).returns(true) table = Table.new table.stubs(:persisted?).returns(true) controller = CentersController.new controller.instance_variable_set('@parent_type', :table) controller.instance_variable_set('@house', house) controller.instance_variable_set('@table', table) # This must not be useful in singleton controllers... # controller.instance_variable_set('@center', :center) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "house_table_#{path_or_url}").with(house, table).once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "house_table_center_#{path_or_url}").with(house, table).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_house_table_center_#{path_or_url}").with(house, table).once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_house_table_center_#{path_or_url}").with(house, table).once controller.send("edit_resource_#{path_or_url}") mock_polymorphic(controller, "house_table_#{path_or_url}").with(house, table).once controller.send("parent_#{path_or_url}") mock_polymorphic(controller, "edit_house_table_#{path_or_url}").with(house, table).once controller.send("edit_parent_#{path_or_url}") end # With options mock_polymorphic(controller, "house_table_center_url").with(house, table, page: 1) controller.send("resource_url", page: 1) mock_polymorphic(controller, "house_table_url").with(house, table, page: 1) controller.send("parent_url", page: 1) # With args controller.expects("polymorphic_url").with([house, table, :center], {}).once controller.send("resource_url", :arg) controller.expects("polymorphic_url").with([house, :arg], {}).once controller.send("parent_url", :arg) end def test_url_helpers_on_optional_polymorphic_belongs_to bed = Bed.new bed.stubs(:persisted?).returns(true) new_bed = Bed.new Bed.stubs(:new).returns(new_bed) new_bed.stubs(:persisted?).returns(false) controller = BedsController.new controller.stubs(:parent_type).returns(nil) controller.instance_variable_set('@bed', bed) [:url, :path].each do |path_or_url| mock_polymorphic(controller, "beds_#{path_or_url}").with().once controller.send("collection_#{path_or_url}") mock_polymorphic(controller, "bed_#{path_or_url}").with(bed).once controller.send("resource_#{path_or_url}") mock_polymorphic(controller, "new_bed_#{path_or_url}").with().once controller.send("new_resource_#{path_or_url}") mock_polymorphic(controller, "edit_bed_#{path_or_url}").with(bed).once controller.send("edit_resource_#{path_or_url}") end # With options mock_polymorphic(controller, "bed_url").with(bed, page: 1).once controller.send("resource_url", page: 1) # With args controller.expects("polymorphic_url").with([:arg], {}).once controller.send("resource_url", :arg) controller.expects("edit_polymorphic_url").with([:arg], {}).once controller.send("edit_resource_url", :arg) end def test_url_helpers_on_belongs_to_with_shallowed_route controller = MirrorsController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@mirror', :mirror) [:url, :path].each do |path_or_url| controller.expects("house_mirrors_#{path_or_url}").with(:house, {}).once controller.send("collection_#{path_or_url}") controller.expects("mirror_#{path_or_url}").with(:mirror, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_house_mirror_#{path_or_url}").with(:house, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_mirror_#{path_or_url}").with(:mirror, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("house_#{path_or_url}").with(:house, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_house_#{path_or_url}").with(:house, {}).once controller.send("edit_parent_#{path_or_url}") end end def test_url_helpers_on_nested_belongs_to_with_shallowed_route controller = ButtonsController.new controller.instance_variable_set('@display', :display) controller.instance_variable_set('@window', :window) controller.instance_variable_set('@button', :button) [:url, :path].each do |path_or_url| controller.expects("window_buttons_#{path_or_url}").with(:window, {}).once controller.send("collection_#{path_or_url}") controller.expects("button_#{path_or_url}").with(:button, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_window_button_#{path_or_url}").with(:window, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_button_#{path_or_url}").with(:button, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("window_#{path_or_url}").with(:window, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_window_#{path_or_url}").with(:window, {}).once controller.send("edit_parent_#{path_or_url}") end end def test_url_helpers_with_custom_actions controller = ButtonsController.new controller.instance_variable_set('@display', :display) controller.instance_variable_set('@window', :window) controller.instance_variable_set('@button', :button) [:url, :path].each do |path_or_url| controller.expects("delete_button_#{path_or_url}").with(:button, {}).once controller.send("delete_resource_#{path_or_url}") controller.expects("search_window_buttons_#{path_or_url}").with(:window, {}).once controller.send("search_resources_#{path_or_url}") end end def test_helper_methods_with_custom_actions controller = ButtonsController.new helper_methods = controller.class._helpers.instance_methods.map {|m| m.to_s } [:url, :path].each do |path_or_url| assert helper_methods.include?("delete_resource_#{path_or_url}") assert helper_methods.include?("search_resources_#{path_or_url}") end end def test_helpers_on_inherited_controller controller = ImageButtonsController.new controller.expects("edit_image_button_path").once controller.send("edit_resource_path") controller.expects("delete_image_button_path").once controller.send("delete_resource_path") end def test_url_helpers_on_namespaced_resource_with_shallowed_route controller = Admin::MirrorsController.new controller.instance_variable_set('@house', :house) controller.instance_variable_set('@mirror', :mirror) [:url, :path].each do |path_or_url| controller.expects("admin_house_mirrors_#{path_or_url}").with(:house, {}).once controller.send("collection_#{path_or_url}") controller.expects("admin_mirror_#{path_or_url}").with(:mirror, {}).once controller.send("resource_#{path_or_url}") controller.expects("new_admin_house_mirror_#{path_or_url}").with(:house, {}).once controller.send("new_resource_#{path_or_url}") controller.expects("edit_admin_mirror_#{path_or_url}").with(:mirror, {}).once controller.send("edit_resource_#{path_or_url}") controller.expects("admin_house_#{path_or_url}").with(:house, {}).once controller.send("parent_#{path_or_url}") controller.expects("edit_admin_house_#{path_or_url}").with(:house, {}).once controller.send("edit_parent_#{path_or_url}") end end def test_url_helpers_with_action_controller_parameters parameters = ActionController::Parameters.new(page: 2) parameters.permit! controller = HousesController.new controller.instance_variable_set('@house', :house) [:url, :path].each do |path_or_url| controller.expects("houses_#{path_or_url}").with({'page' => 2}).once controller.send("collection_#{path_or_url}", parameters) end end end inherited_resources-1.13.0/test/views/000077500000000000000000000000001404526035200177565ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/address/000077500000000000000000000000001404526035200214035ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/address/edit.html.erb000066400000000000000000000000121404526035200237560ustar00rootroot00000000000000edit html inherited_resources-1.13.0/test/views/address/new.html.erb000066400000000000000000000000111404526035200236210ustar00rootroot00000000000000new html inherited_resources-1.13.0/test/views/address/show.html.erb000066400000000000000000000000121404526035200240110ustar00rootroot00000000000000show html inherited_resources-1.13.0/test/views/cars/000077500000000000000000000000001404526035200207065ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/cars/edit.html.erb000066400000000000000000000000121404526035200232610ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/cars/index.html.erb000066400000000000000000000000131404526035200234440ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/cars/new.html.erb000066400000000000000000000000111404526035200231240ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/cars/show.html.erb000066400000000000000000000000121404526035200233140ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/cities/000077500000000000000000000000001404526035200212365ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/cities/edit.html.erb000066400000000000000000000000121404526035200236110ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/cities/index.html.erb000066400000000000000000000000131404526035200237740ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/cities/new.html.erb000066400000000000000000000000111404526035200234540ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/cities/show.html.erb000066400000000000000000000000121404526035200236440ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/comments/000077500000000000000000000000001404526035200216035ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/comments/edit.html.erb000066400000000000000000000000121404526035200241560ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/comments/index.html.erb000066400000000000000000000000131404526035200243410ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/comments/new.html.erb000066400000000000000000000000111404526035200240210ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/comments/show.html.erb000066400000000000000000000000121404526035200242110ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/educations/000077500000000000000000000000001404526035200221145ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/educations/new.html.erb000066400000000000000000000000001404526035200243300ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/employees/000077500000000000000000000000001404526035200217605ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/employees/edit.html.erb000066400000000000000000000000121404526035200243330ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/employees/index.html.erb000066400000000000000000000000131404526035200245160ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/employees/new.html.erb000066400000000000000000000000111404526035200241760ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/employees/show.html.erb000066400000000000000000000000121404526035200243660ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/geolocation/000077500000000000000000000000001404526035200222615ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/geolocation/show.html.erb000066400000000000000000000000121404526035200246670ustar00rootroot00000000000000show html inherited_resources-1.13.0/test/views/groups/000077500000000000000000000000001404526035200212755ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/groups/edit.html.erb000066400000000000000000000000001404526035200236450ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/managers/000077500000000000000000000000001404526035200215535ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/managers/edit.html.erb000066400000000000000000000000121404526035200241260ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/managers/new.html.erb000066400000000000000000000000111404526035200237710ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/managers/show.html.erb000066400000000000000000000000121404526035200241610ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/painters/000077500000000000000000000000001404526035200216035ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/painters/edit.html.erb000066400000000000000000000000121404526035200241560ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/painters/index.html.erb000066400000000000000000000000131404526035200243410ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/painters/new.html.erb000066400000000000000000000000111404526035200240210ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/painters/show.html.erb000066400000000000000000000000121404526035200242110ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/pets/000077500000000000000000000000001404526035200207315ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/pets/edit.html.erb000066400000000000000000000000121404526035200233040ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/pets/index.html.erb000066400000000000000000000000131404526035200234670ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/pets/new.html.erb000066400000000000000000000000111404526035200231470ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/pets/show.html.erb000066400000000000000000000000121404526035200233370ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/photos/000077500000000000000000000000001404526035200212725ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/photos/index.html.erb000066400000000000000000000000131404526035200240300ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/plates/000077500000000000000000000000001404526035200212465ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/plates/edit.html.erb000066400000000000000000000000121404526035200236210ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/plates/index.html.erb000066400000000000000000000000131404526035200240040ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/plates/new.html.erb000066400000000000000000000000111404526035200234640ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/plates/show.html.erb000066400000000000000000000000121404526035200236540ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/products/000077500000000000000000000000001404526035200216215ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/products/edit.html.erb000066400000000000000000000000121404526035200241740ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/products/index.html.erb000066400000000000000000000000131404526035200243570ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/products/new.html.erb000066400000000000000000000000111404526035200240370ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/products/show.html.erb000066400000000000000000000000121404526035200242270ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/professors/000077500000000000000000000000001404526035200221635ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/professors/edit.html.erb000066400000000000000000000000121404526035200245360ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/professors/index.html.erb000066400000000000000000000000131404526035200247210ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/professors/new.html.erb000066400000000000000000000000111404526035200244010ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/professors/show.html.erb000066400000000000000000000000121404526035200245710ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/projects/000077500000000000000000000000001404526035200216075ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/projects/edit.html.erb000066400000000000000000000000111404526035200241610ustar00rootroot00000000000000Edit HTMLinherited_resources-1.13.0/test/views/projects/index.html.erb000066400000000000000000000000131404526035200243450ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/projects/index.json.erb000066400000000000000000000000131404526035200243520ustar00rootroot00000000000000Index JSON inherited_resources-1.13.0/test/views/projects/new.html.erb000066400000000000000000000000101404526035200240240ustar00rootroot00000000000000New HTMLinherited_resources-1.13.0/test/views/projects/respond_to_skip_default_template.html.erb000066400000000000000000000000251404526035200320420ustar00rootroot00000000000000DefaultTemplate HTML inherited_resources-1.13.0/test/views/projects/respond_with_resource.html.erb000066400000000000000000000000171404526035200276560ustar00rootroot00000000000000RespondTo HTML inherited_resources-1.13.0/test/views/projects/show.html.erb000066400000000000000000000000111404526035200242140ustar00rootroot00000000000000Show HTMLinherited_resources-1.13.0/test/views/students/000077500000000000000000000000001404526035200216275ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/students/edit.html.erb000066400000000000000000000000121404526035200242020ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/students/new.html.erb000066400000000000000000000000111404526035200240450ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/tags/000077500000000000000000000000001404526035200207145ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/tags/edit.html.erb000066400000000000000000000000121404526035200232670ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/tags/index.html.erb000066400000000000000000000000131404526035200234520ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/tags/new.html.erb000066400000000000000000000000111404526035200231320ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/tags/show.html.erb000066400000000000000000000000121404526035200233220ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/trees/000077500000000000000000000000001404526035200211005ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/trees/edit.html.erb000066400000000000000000000000121404526035200234530ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/trees/index.html.erb000066400000000000000000000000131404526035200236360ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/trees/new.html.erb000066400000000000000000000000111404526035200233160ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/trees/show.html.erb000066400000000000000000000000121404526035200235060ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/university/000077500000000000000000000000001404526035200221775ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/university/lecturers/000077500000000000000000000000001404526035200242075ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/university/lecturers/edit.html.erb000066400000000000000000000000121404526035200265620ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/university/lecturers/index.html.erb000066400000000000000000000000131404526035200267450ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/university/lecturers/new.html.erb000066400000000000000000000000111404526035200264250ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/university/lecturers/show.html.erb000066400000000000000000000000121404526035200266150ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/users/000077500000000000000000000000001404526035200211175ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/users/create.js.erb000066400000000000000000000000111404526035200234570ustar00rootroot00000000000000Create JSinherited_resources-1.13.0/test/views/users/destroy.js.erb000066400000000000000000000000121404526035200237060ustar00rootroot00000000000000Destroy JSinherited_resources-1.13.0/test/views/users/edit.html.erb000066400000000000000000000000121404526035200234720ustar00rootroot00000000000000Edit HTML inherited_resources-1.13.0/test/views/users/index.html.erb000066400000000000000000000000131404526035200236550ustar00rootroot00000000000000Index HTML inherited_resources-1.13.0/test/views/users/new.html.erb000066400000000000000000000000111404526035200233350ustar00rootroot00000000000000New HTML inherited_resources-1.13.0/test/views/users/show.html.erb000066400000000000000000000000121404526035200235250ustar00rootroot00000000000000Show HTML inherited_resources-1.13.0/test/views/users/update.js.erb000066400000000000000000000000111404526035200234760ustar00rootroot00000000000000Update JSinherited_resources-1.13.0/test/views/venue/000077500000000000000000000000001404526035200211005ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/venue/show.html.erb000066400000000000000000000000121404526035200235060ustar00rootroot00000000000000show html inherited_resources-1.13.0/test/views/widgets/000077500000000000000000000000001404526035200214245ustar00rootroot00000000000000inherited_resources-1.13.0/test/views/widgets/new.html.erb000066400000000000000000000000001404526035200236400ustar00rootroot00000000000000