├── .gitignore ├── .rubocop.yml ├── .ruby-gemset ├── .ruby-version ├── .travis.yml ├── CHANGELOG.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── arpa.gemspec ├── lib ├── arpa.rb ├── arpa │ ├── additions │ │ └── resource.rb │ ├── data_mappers │ │ ├── action_mapper.rb │ │ ├── base.rb │ │ ├── profile_mapper.rb │ │ ├── resource_mapper.rb │ │ └── role_mapper.rb │ ├── entities │ │ ├── action.rb │ │ ├── profile.rb │ │ ├── resource.rb │ │ └── role.rb │ ├── exceptions │ │ └── record_invalid.rb │ ├── repositories │ │ ├── actions │ │ │ ├── creator.rb │ │ │ ├── finder.rb │ │ │ ├── remover.rb │ │ │ └── repository_action.rb │ │ ├── base.rb │ │ ├── profiles │ │ │ ├── creator.rb │ │ │ ├── finder.rb │ │ │ ├── remover.rb │ │ │ ├── repository_profile.rb │ │ │ └── updater.rb │ │ ├── registrator.rb │ │ ├── resources │ │ │ ├── creator.rb │ │ │ ├── finder.rb │ │ │ ├── remover.rb │ │ │ └── repository_resource.rb │ │ └── roles │ │ │ ├── creator.rb │ │ │ ├── finder.rb │ │ │ ├── remover.rb │ │ │ ├── repository_role.rb │ │ │ └── updater.rb │ ├── services │ │ ├── actions │ │ │ ├── create │ │ │ │ └── action_creator.rb │ │ │ └── remove │ │ │ │ └── action_remover.rb │ │ ├── base.rb │ │ ├── profiles │ │ │ ├── create │ │ │ │ └── profile_creator.rb │ │ │ ├── profile_manager_creator.rb │ │ │ ├── profile_manager_remover.rb │ │ │ ├── profile_manager_updater.rb │ │ │ ├── remove │ │ │ │ └── profile_remover.rb │ │ │ └── update │ │ │ │ └── profile_updater.rb │ │ ├── resources │ │ │ ├── create │ │ │ │ └── resource_creator.rb │ │ │ ├── remove │ │ │ │ └── resource_remover.rb │ │ │ └── resource_manager_creator.rb │ │ ├── roles │ │ │ ├── create │ │ │ │ └── role_creator.rb │ │ │ ├── remove │ │ │ │ └── role_remover.rb │ │ │ ├── role_manager_creator.rb │ │ │ ├── role_manager_remover.rb │ │ │ ├── role_manager_updater.rb │ │ │ └── update │ │ │ │ └── role_updater.rb │ │ └── verifier.rb │ ├── validators │ │ ├── action_validator.rb │ │ ├── profile_validator.rb │ │ ├── resource_validator.rb │ │ └── role_validator.rb │ └── version.rb ├── config │ └── locales │ │ └── arpa.en.yml └── generators │ └── arpa │ ├── controllers_generator.rb │ ├── install_generator.rb │ └── templates │ ├── assets │ └── stylesheets │ │ └── arpa_accordion.scss │ ├── controllers │ ├── profiles_controller.rb │ ├── resources_controller.rb │ └── roles_controller.rb │ ├── migration.rb │ └── views │ ├── profiles │ ├── _form.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb │ ├── resources │ ├── index.html.erb │ └── show.html.erb │ └── roles │ ├── _form.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb └── spec ├── factories ├── repository_actions.rb ├── repository_profiles.rb ├── repository_resources.rb ├── repository_roles.rb └── repository_test.rb ├── lib └── arpa │ ├── additions │ └── resource_spec.rb │ ├── data_mappers │ ├── action_mapper_spec.rb │ ├── base_spec.rb │ ├── profile_mapper_spec.rb │ ├── resource_mapper_spec.rb │ └── role_mapper_spec.rb │ ├── entities │ ├── action_spec.rb │ ├── profile_spec.rb │ ├── resource_spec.rb │ └── role_spec.rb │ ├── repositories │ ├── actions │ │ └── finder_spec.rb │ ├── base_spec.rb │ ├── profiles │ │ ├── finder_spec.rb │ │ └── remover_spec.rb │ ├── resources │ │ ├── finder_spec.rb │ │ └── remover_spec.rb │ └── roles │ │ ├── finder_spec.rb │ │ └── remover_spec.rb │ ├── requests │ ├── profiles │ │ ├── create_request_spec.rb │ │ └── remove_request_spec.rb │ ├── resources │ │ └── create_request_spec.rb │ └── roles │ │ ├── create_request_spec.rb │ │ ├── remove_request_spec.rb │ │ └── update_request_spec.rb │ ├── services │ ├── actions │ │ ├── create │ │ │ └── action_creator_spec.rb │ │ └── remove │ │ │ └── action_remover_spec.rb │ ├── base_spec.rb │ ├── profiles │ │ ├── create │ │ │ └── profile_creator_spec.rb │ │ ├── profile_manager_creator_spec.rb │ │ ├── profile_manager_remover_spec.rb │ │ ├── profile_manager_updater_spec.rb │ │ ├── remove │ │ │ └── profile_remover_spec.rb │ │ └── update │ │ │ └── profile_updater_spec.rb │ ├── resources │ │ ├── create │ │ │ └── resource_creator_spec.rb │ │ ├── remove │ │ │ └── resource_remover_spec.rb │ │ └── resource_manager_creator_spec.rb │ ├── roles │ │ ├── create │ │ │ └── role_creator_spec.rb │ │ ├── remove │ │ │ └── role_remover_spec.rb │ │ ├── role_manager_creator_spec.rb │ │ ├── role_manager_remover_spec.rb │ │ ├── role_manager_updater_spec.rb │ │ └── update │ │ │ └── role_updater_spec.rb │ └── verifier_spec.rb │ └── validators │ ├── action_validator_spec.rb │ ├── profile_validator_spec.rb │ ├── resource_validator_spec.rb │ └── role_validator_spec.rb ├── spec_helper.rb └── support ├── repositories └── test_repository.rb └── schema.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | *.sqlite3 10 | /tmp/ 11 | *.bundle 12 | *.so 13 | *.o 14 | *.a 15 | *.gem 16 | mkmf.log 17 | 18 | # scm revert files 19 | **.orig 20 | 21 | # Mac finder artifacts 22 | .DS_Store 23 | 24 | # RubyMine project files 25 | .idea 26 | 27 | # vim artifacts 28 | **.swp 29 | 30 | # Environment files that may contain sensitive data 31 | .env 32 | .powenv 33 | 34 | # Ignoring .keep files 35 | .keep 36 | 37 | # Elastic Beanstalk Files 38 | .elasticbeanstalk/* 39 | !.elasticbeanstalk/*.cfg.yml 40 | !.elasticbeanstalk/*.global.yml 41 | 42 | Procfile 43 | .vagrant 44 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | DisplayCopNames: true 3 | DisplayStyleGuide: true 4 | ExtraDetails: false 5 | TargetRubyVersion: 2.5 6 | 7 | Metrics/LineLength: 8 | Max: 120 9 | 10 | Metrics/BlockLength: 11 | ExcludedMethods: ['describe', 'context', 'define'] 12 | 13 | Style/Documentation: 14 | Enabled: false 15 | 16 | Style/FrozenStringLiteralComment: 17 | Enabled: false 18 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | arpa 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.5.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.2.0 4 | - 2.4.2 5 | script: bundle exec rspec spec 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 0.3.0 2 | * changes 3 | * Update project to use rails 5.2 4 | 5 | ### 0.2.0 6 | 7 | * additions 8 | * Add dinamic association for Profiles throuh Entity id and class attriutes; 9 | * Add find methods to collect all Profiles without Entity and with specific entity; 10 | * Update all views and controllers with the new attriutes for Profile. 11 | 12 | ### 0.0.9 13 | 14 | * removals 15 | * Change the necessity to use `session` for `Arpa::Additions::Resource`. 16 | * Change the necessity to pass `session` as parameter on initialize for `Arpa::Services::Verifier`. 17 | * Remove from `session` to store all user permissions. 18 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in arpa.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Rachid Calazans 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arpa 2 | 3 | Arpa is an authorization library for Ruby or Ruby on Rails which restricts the accesses in controller and actions. Arpa will help you to customize all permissions you need dynamically. 4 | 5 | ## Installation 6 | 7 | Add this line to your application's Gemfile: 8 | 9 | ```ruby 10 | gem 'arpa' 11 | ``` 12 | 13 | And then execute: 14 | 15 | $ bundle 16 | 17 | Or install it yourself as: 18 | 19 | $ gem install arpa 20 | 21 | After you install Arpa and add it to your Gemfile, you need to run the generator: 22 | 23 | $ rails generate arpa:install 24 | 25 | This command will create some files that are needed to run the Gem. 26 | 27 | | File | Purpose | 28 | |----------|:-------------:| 29 | | db/migrate/20140120201010_create_arpa_tables.rb | Migration to create the all **Arpa** tables in your database (your name will include a different timestamp) | 30 | | config/locales/arpa.en.yml | Locales to use in Arpa classes | 31 | 32 | **Obs.:** The migration file will create a associate table between **Arpa::Profile** and **SomeModel**. By **default** the model is **User** as **users** table. The model to associate must exist in your Application before run that generate. 33 | 34 | If you want a different Model to associate with Arpa::Profile you can pass some arguments: 35 | 36 | $ rails generate arpa:install [ASSOCIATE_TABLE] [ASSOCIATE_PRIMARY_KEY] 37 | 38 | #### Eg. 1: 39 | 40 | $ rails generate arpa:install admins 41 | 42 | That command will create the association with **admins** table with **admin_id** as foreign key. 43 | 44 | #### Eg. 2: 45 | 46 | $ rails generate arpa:install admins admin_custom_id 47 | 48 | That command will create the association with **admins** table with **admin_custom_id** as foreign key. 49 | 50 | 51 | After run the generate command, you need to run the migration to create all Arpa tables: 52 | 53 | $ rake db:migrate 54 | 55 | --- 56 | 57 | Arpa can generate the *Controllers*, *Views*, *Stylesheet* and *Routes* to a basic CRUD for *resources*, *roles* and *profiles*. To do that you can run: 58 | 59 | $ rails generate arpa:controllers 60 | 61 | This command will create some files. 62 | 63 | | File | Purpose | 64 | |----------|:-------------:| 65 | | app/assets/stylesheets/arpa/arpa_accordion.scss | Basic stylesheet to use with Arpa views | 66 | | app/controllers/arpa/resources_controller.rb app/controllers/arpa/roles_controller.rb app/controllers/arpa/profiles_controller.rb | Controllers to use the CRUD actions for each one | 67 | | app/views/arpa/resources/ app/controllers/arpa/roles/ app/controllers/arpa/profiles/ | All views to use the CRUD actions for each controller above | 68 | | config/routes.rb | Will add all routes into this file with all resources of Arpa | 69 | 70 | 71 | ## Usage 72 | 73 | First of all you must create the Resources, Roles and Profiles (each is avaliable in the paths listed in a section bellow). After that you need associate **Arpa::Profile** with **SomeModel** (to do this, you need create by your own the associate form view, saving some profiles in some model). Done that you can use some Helpers generated by Arpa. 74 | 75 | ### Association between Arpa::Profile and SomeModel 76 | 77 | You just need have a method called **:profile_ids** inside the **SomeModel** model. This method should return a list of ids from profiles associated in the model. 78 | 79 | You just add a HBTM association in SomeModel model: 80 | 81 | ```ruby 82 | class User < ActiveRecord::Base 83 | has_and_belongs_to_many :profiles, class_name: 'Arpa::Repositories::Profiles::RepositoryProfile' 84 | end 85 | ``` 86 | With this you will be able to use the :profile_ids method. 87 | 88 | If the Model name is different on database you need add the **foreign_key** option: 89 | 90 | ```ruby 91 | class User < ActiveRecord::Base 92 | self.table_name = 'admins' 93 | 94 | has_and_belongs_to_many :profiles, class_name: 'Arpa::Repositories::Profiles::RepositoryProfile', foreign_key: 'admin_id' 95 | end 96 | ``` 97 | 98 | ### Controller helpers 99 | 100 | Arpa will create some helpers to use inside your controllers and views. 101 | 102 | To verify if a user has access to some :controler and :action, use the following helper: 103 | 104 | ```ruby 105 | has_access?('users', 'index') 106 | ``` 107 | 108 | 109 | **Obs.:** To that helper method works. You must have **:current_user** attribute or method. 110 | 111 | --- 112 | If you want use that methods inside another object you should use the **Arpa::Services::Verifier** class; 113 | 114 | You just need pass as arguments the :session and :current_user: 115 | 116 | ```ruby 117 | verifier = Arpa::Services::Verifier.new(current_user) 118 | verifier.has_access?('users', 'index') 119 | ``` 120 | 121 | ### Controller Filter 122 | 123 | If you want create a filter to verify if the current_user has access and if not redirect to another route you can do this: 124 | 125 | Create a method in ApplicationController and add as a before_filter callback from rails: 126 | 127 | ```ruby 128 | class ApplicationController < ActionController::Base 129 | before_filter :authorize_user 130 | 131 | def authorize_user 132 | controller = params[:controller] 133 | action = params[:action] 134 | redirect_to some_url unless has_access?(controller, action) 135 | end 136 | 137 | end 138 | ``` 139 | 140 | **Obs. 1:** The **has_access?** method come from Controller Helper method which Arpa gem has been created. 141 | 142 | **Obs. 2:** When you create the **before_filter** you probably wanna skip that callback in somes **controllers** (like login or devise controllers). To do this you need set the **skip_before_action** passing as parameter the name of before_filter method as you can see bellow: 143 | 144 | ```ruby 145 | skip_before_action :authorize_user 146 | ``` 147 | 148 | 149 | ## Descriptions Locales for Arpa::Entities::Action 150 | 151 | Arpa will use on **description** method from Arpa::Entities::Action a specific Locale. 152 | 153 | You should create a locale file to print correctly the descriptions of the actions. 154 | 155 | #### Eg.: 156 | 157 | ```ruby 158 | en: 159 | entities: 160 | resources: 161 | users: #Here is the name of controller 162 | actions: 163 | description: 164 | #Here is each action of the controller 165 | index: 'List of Users' 166 | show: 'Show of User' 167 | new: 'Access to registration form of User' 168 | edit: 'Access to change form of User' 169 | create: 'Perform action registering of User' 170 | update: 'Perform action update of User' 171 | destroy: 'Perform action destroy of User' 172 | 173 | ``` 174 | 175 | ## Information 176 | 177 | Arpa will add a new column called **is_arpa_admin** as boolean in the associate table with value **false** as default. You must set some user (creating a migration for example), with *is_arpa_admin* as **true** to navigate between the views without be catched by the filter verification. 178 | 179 | If you want a **action** of some **Controller** pass without permission on *before_filter* callback. You just need start the name of action with underscode ('_'). For example: 180 | 181 | ```ruby 182 | def _some_free_action_which_not_need_permission 183 | end 184 | ``` 185 | 186 | 187 | The routes created by **arpa:controllers** generator will be able to access some paths for each Controller created: 188 | 189 | ```ruby 190 | generate_resources_and_actions_resources GET /resources/generate_resources_and_actions(.:format) arpa/resources#generate_resources_and_actions 191 | resources GET /resources(.:format) arpa/resources#index 192 | POST /resources(.:format) arpa/resources#create 193 | new_resource GET /resources/new(.:format) arpa/resources#new 194 | edit_resource GET /resources/:id/edit(.:format) arpa/resources#edit 195 | resource GET /resources/:id(.:format) arpa/resources#show 196 | PATCH /resources/:id(.:format) arpa/resources#update 197 | PUT /resources/:id(.:format) arpa/resources#update 198 | DELETE /resources/:id(.:format) arpa/resources#destroy 199 | DELETE /roles/:id(.:format) arpa/roles#remove 200 | roles GET /roles(.:format) arpa/roles#index 201 | POST /roles(.:format) arpa/roles#create 202 | new_role GET /roles/new(.:format) arpa/roles#new 203 | edit_role GET /roles/:id/edit(.:format) arpa/roles#edit 204 | role GET /roles/:id(.:format) arpa/roles#show 205 | PATCH /roles/:id(.:format) arpa/roles#update 206 | PUT /roles/:id(.:format) arpa/roles#update 207 | DELETE /roles/:id(.:format) arpa/roles#destroy 208 | DELETE /profiles/:id(.:format) arpa/profiles#remove 209 | profiles GET /profiles(.:format) arpa/profiles#index 210 | POST /profiles(.:format) arpa/profiles#create 211 | new_profile GET /profiles/new(.:format) arpa/profiles#new 212 | edit_profile GET /profiles/:id/edit(.:format) arpa/profiles#edit 213 | profile GET /profiles/:id(.:format) arpa/profiles#show 214 | PATCH /profiles/:id(.:format) arpa/profiles#update 215 | PUT /profiles/:id(.:format) arpa/profiles#update 216 | DELETE /profiles/:id(.:format) arpa/profiles#destroy 217 | ``` 218 | 219 | ## License 220 | 221 | MIT License. Copyright Rachid Calazans. 222 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | -------------------------------------------------------------------------------- /arpa.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('lib', __dir__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | require 'arpa/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = 'arpa' 7 | spec.version = Arpa::VERSION 8 | spec.authors = ['Rachid Calazans'] 9 | spec.summary = 'Authorization Gem for Ruby and Ruby on Rails projects' 10 | spec.email = ['rachidcalazans@gmail.com'] 11 | spec.license = 'MIT' 12 | spec.homepage = 'https://github.com/rachidcalazans/arpa' 13 | spec.description = 'Authorization Gem for Ruby and Ruby on Rails projects' 14 | 15 | spec.files = `git ls-files -z`.split("\x0") 16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ['lib'] 19 | 20 | spec.add_development_dependency 'bundler' 21 | spec.add_development_dependency 'database_cleaner' 22 | spec.add_development_dependency 'factory_bot' 23 | spec.add_development_dependency 'pry' 24 | spec.add_development_dependency 'rake' 25 | spec.add_development_dependency 'rspec' 26 | spec.add_development_dependency 'rubocop' 27 | spec.add_development_dependency 'sqlite3' 28 | 29 | spec.add_dependency 'activerecord' 30 | spec.add_dependency 'railties' 31 | end 32 | -------------------------------------------------------------------------------- /lib/arpa.rb: -------------------------------------------------------------------------------- 1 | require 'arpa/version' 2 | require 'rails/railtie' 3 | 4 | # Additions 5 | require 'arpa/additions/resource' 6 | 7 | # Exceptions 8 | require 'arpa/exceptions/record_invalid' 9 | 10 | # Entities 11 | require 'arpa/entities/resource' 12 | require 'arpa/entities/action' 13 | require 'arpa/entities/role' 14 | require 'arpa/entities/profile' 15 | 16 | # Mappers 17 | require 'arpa/data_mappers/base' 18 | require 'arpa/data_mappers/resource_mapper' 19 | require 'arpa/data_mappers/action_mapper' 20 | require 'arpa/data_mappers/role_mapper' 21 | require 'arpa/data_mappers/profile_mapper' 22 | 23 | # Validators 24 | require 'arpa/validators/resource_validator' 25 | require 'arpa/validators/action_validator' 26 | require 'arpa/validators/role_validator' 27 | require 'arpa/validators/profile_validator' 28 | 29 | # Repositories 30 | require 'arpa/repositories/base' 31 | require 'arpa/repositories/registrator' 32 | 33 | require 'arpa/repositories/resources/repository_resource' 34 | require 'arpa/repositories/resources/finder' 35 | require 'arpa/repositories/resources/remover' 36 | require 'arpa/repositories/resources/creator' 37 | 38 | require 'arpa/repositories/actions/repository_action' 39 | require 'arpa/repositories/actions/finder' 40 | require 'arpa/repositories/actions/remover' 41 | require 'arpa/repositories/actions/creator' 42 | 43 | require 'arpa/repositories/roles/repository_role' 44 | require 'arpa/repositories/roles/finder' 45 | require 'arpa/repositories/roles/creator' 46 | require 'arpa/repositories/roles/updater' 47 | require 'arpa/repositories/roles/remover' 48 | 49 | require 'arpa/repositories/profiles/repository_profile' 50 | require 'arpa/repositories/profiles/finder' 51 | require 'arpa/repositories/profiles/creator' 52 | require 'arpa/repositories/profiles/updater' 53 | require 'arpa/repositories/profiles/remover' 54 | 55 | # Services 56 | require 'arpa/services/base' 57 | require 'arpa/services/verifier' 58 | 59 | require 'arpa/services/actions/create/action_creator' 60 | require 'arpa/services/actions/remove/action_remover' 61 | 62 | require 'arpa/services/resources/create/resource_creator' 63 | require 'arpa/services/resources/remove/resource_remover' 64 | require 'arpa/services/resources/resource_manager_creator' 65 | 66 | require 'arpa/services/roles/role_manager_creator' 67 | require 'arpa/services/roles/role_manager_updater' 68 | require 'arpa/services/roles/role_manager_remover' 69 | require 'arpa/services/roles/create/role_creator' 70 | require 'arpa/services/roles/update/role_updater' 71 | require 'arpa/services/roles/remove/role_remover' 72 | 73 | require 'arpa/services/profiles/profile_manager_creator' 74 | require 'arpa/services/profiles/profile_manager_updater' 75 | require 'arpa/services/profiles/profile_manager_remover' 76 | require 'arpa/services/profiles/create/profile_creator' 77 | require 'arpa/services/profiles/update/profile_updater' 78 | require 'arpa/services/profiles/remove/profile_remover' 79 | 80 | module Arpa 81 | class Railtie < ::Rails::Railtie 82 | initializer 'arpa.configure_view_controller' do |_app| 83 | ActiveSupport.on_load :action_controller do 84 | include Arpa::Additions::Resource 85 | end 86 | end 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /lib/arpa/additions/resource.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Additions 3 | module Resource 4 | def self.included(base) 5 | base.helper_method :has_access? 6 | end 7 | 8 | def has_access?(resource, action) 9 | return unless has_current_user? 10 | verifier.has_access?(resource, action) 11 | end 12 | 13 | def verifier 14 | @verifier ||= Arpa::Services::Verifier.new(current_user) 15 | end 16 | 17 | private 18 | 19 | def has_current_user? 20 | verified_current_user = try(:current_user) 21 | return true if verified_current_user 22 | log = Logger.new(STDOUT) 23 | log.warn("The ApplicationController must has a attribute or method 'current_user'") unless verified_current_user 24 | false 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/arpa/data_mappers/action_mapper.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module DataMappers 3 | class ActionMapper < Base 4 | entity_class 'Arpa::Entities::Action' 5 | repository_class 'Arpa::Repositories::Actions::RepositoryAction' 6 | 7 | attrs_to_entity :id, :resource_id, :name, :created_at, :updated_at, 8 | resource: { mapper: 'Arpa::DataMappers::ResourceMapper' } 9 | attrs_to_record :id, :resource_id, :name, :created_at, :updated_at 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/arpa/data_mappers/base.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module DataMappers 3 | class Base 4 | include Singleton 5 | 6 | def map_to_record(entity, options = {}) 7 | options[:map_association_to] ||= :map_to_record 8 | attrs_to_record = self.class._attrs_to_record 9 | attributes = attributes_from(entity, attrs_to_record, options) 10 | self.class._repository_class.new(attributes) 11 | end 12 | 13 | def map_to_entity(record, options = {}) 14 | options[:map_association_to] ||= :map_to_entity 15 | attrs_to_entity = self.class._attrs_to_entity 16 | attributes = attributes_from(record, attrs_to_entity, options) 17 | self.class._entity_class.new(attributes) 18 | end 19 | 20 | private 21 | 22 | def attributes_from(object, attrs_to_map, options = {}) 23 | options[:map_association_to] = options.fetch(:map_association_to, :map_to_entity) 24 | options[:map_association] = options.fetch(:map_association, true) 25 | 26 | attrs_to_map ||= self.class._attributes_to_map 27 | 28 | begin 29 | build_hash_attributes(attrs_to_map, object, options) 30 | rescue StandardError => e 31 | raise StandardError, "#{self.class} -> #{e.message}" 32 | end 33 | end 34 | 35 | def build_hash_attributes(attributes_to_map, object, options) 36 | builder_attribute = build_hash_attribute.curry.call(object, options) 37 | 38 | attributes_to_map.collect do |attr_key| 39 | builder_attribute.call(attr_key) 40 | end.reduce({}, :merge) 41 | end 42 | 43 | def build_hash_attribute 44 | lambda { |object, options, attr_key| 45 | if attr_key.is_a?(Hash) 46 | key = attr_key.keys.first 47 | value = association_value(object, attr_key, options) 48 | else 49 | key = attr_key 50 | value = object.send(attr_key) if object.respond_to?(attr_key) 51 | end 52 | { :"#{key}" => value } 53 | } 54 | end 55 | 56 | def association_value(object, attr_key, options) 57 | key = attr_key.keys.first 58 | object_value = object.send(key) 59 | 60 | return object_value unless options[:map_association] 61 | 62 | mapper = attr_key[key][:mapper].constantize.instance 63 | 64 | if object_value.try(:size) 65 | object_value.collect do |obj| 66 | mapper.send(options[:map_association_to], obj, map_association: false) 67 | end 68 | else 69 | mapper.send(options[:map_association_to], object_value, map_association: false) 70 | end 71 | end 72 | 73 | # --- Classes Methods --- 74 | 75 | def self.entity_class(entity_class) 76 | @entity_class = entity_class 77 | end 78 | 79 | def self._entity_class 80 | @entity_class.constantize 81 | end 82 | 83 | def self.repository_class(repository_class) 84 | @repository_class = repository_class 85 | end 86 | 87 | def self._repository_class 88 | @repository_class.constantize 89 | end 90 | 91 | def self.attributes_to_map(*attrs) 92 | @attributes_to_map = attrs 93 | end 94 | 95 | def self.attrs_to_record(*attrs) 96 | @attrs_to_record = attrs 97 | end 98 | 99 | def self.attrs_to_entity(*attrs) 100 | @attrs_to_entity = attrs 101 | end 102 | 103 | def self._attributes_to_map 104 | @attributes_to_map 105 | end 106 | 107 | def self._attrs_to_record 108 | @attrs_to_record 109 | end 110 | 111 | def self._attrs_to_entity 112 | @attrs_to_entity 113 | end 114 | end 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /lib/arpa/data_mappers/profile_mapper.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module DataMappers 3 | class ProfileMapper < Base 4 | entity_class 'Arpa::Entities::Profile' 5 | repository_class 'Arpa::Repositories::Profiles::RepositoryProfile' 6 | 7 | attrs_to_entity :id, :name, :description, :role_ids, :entity_id, :entity_class, 8 | :created_at, :updated_at, :removed, 9 | roles: { mapper: 'Arpa::DataMappers::RoleMapper' } 10 | 11 | attrs_to_record :id, :name, :description, :role_ids, :entity_id, :entity_class, 12 | :created_at, :updated_at, :removed 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/arpa/data_mappers/resource_mapper.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module DataMappers 3 | class ResourceMapper < Base 4 | entity_class 'Arpa::Entities::Resource' 5 | repository_class 'Arpa::Repositories::Resources::RepositoryResource' 6 | 7 | attributes_to_map :id, :name, :full_name, 8 | actions: { mapper: 'Arpa::DataMappers::ActionMapper' } 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/arpa/data_mappers/role_mapper.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module DataMappers 3 | class RoleMapper < Base 4 | entity_class 'Arpa::Entities::Role' 5 | repository_class 'Arpa::Repositories::Roles::RepositoryRole' 6 | 7 | attrs_to_entity :id, :name, :description, :action_ids, :removed, :created_at, :updated_at, 8 | { actions: { mapper: 'Arpa::DataMappers::ActionMapper' } }, 9 | profiles: { mapper: 'Arpa::DataMappers::ProfileMapper' } 10 | 11 | attrs_to_record :id, :name, :description, :action_ids, :removed, :created_at, :updated_at 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/arpa/entities/action.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Entities 3 | class Action 4 | attr_reader :id, :resource_id, :resource, :name, :created_at, :updated_at 5 | 6 | def initialize(attrs = {}) 7 | attrs = attrs.with_indifferent_access 8 | 9 | @id = attrs[:id] 10 | @resource_id = attrs[:resource_id] 11 | @resource = attrs[:resource] 12 | @name = attrs[:name] 13 | @created_at = attrs[:created_at] 14 | @updated_at = attrs[:updated_at] 15 | end 16 | 17 | def resource_name 18 | return resource.name if resource 19 | '' 20 | end 21 | 22 | def description 23 | I18n.t(name.to_sym, scope: "entities.resources.#{resource_name}.actions.description") 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/arpa/entities/profile.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Entities 3 | class Profile 4 | attr_reader :id, :name, :description, :role_ids, :roles, :entity_id, :entity_class, 5 | :created_at, :updated_at, :removed 6 | 7 | def initialize(attrs = {}) 8 | attrs = attrs.with_indifferent_access 9 | 10 | @id = attrs[:id] 11 | @name = attrs[:name] 12 | @description = attrs[:description] 13 | @role_ids = default_value_to_nil_or_empty(attrs[:role_ids], []) 14 | @roles = default_value_to_nil_or_empty(attrs[:roles], []) 15 | @entity_id = attrs[:entity_id] 16 | @entity_class = attrs[:entity_class] 17 | @created_at = attrs[:created_at] 18 | @updated_at = attrs[:updated_at] 19 | @removed = default_value_to_nil_or_empty(attrs[:removed], false) 20 | end 21 | 22 | private 23 | 24 | def default_value_to_nil_or_empty(attr_value, default_value) 25 | return attr_value if attr_value.present? 26 | default_value 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/arpa/entities/resource.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Entities 3 | class Resource 4 | attr_reader :id, :full_name, :name, :created_at, :updated_at, :actions 5 | 6 | def initialize(attrs = {}) 7 | attrs = attrs.with_indifferent_access 8 | 9 | @id = attrs[:id] 10 | @full_name = attrs[:full_name] 11 | @name = attrs[:name] 12 | @created_at = attrs[:created_at] 13 | @updated_at = attrs[:updated_at] 14 | @actions = attrs[:actions].present? ? attrs[:actions] : [] 15 | end 16 | 17 | def build_correct_name 18 | name = remove_word(full_name) 19 | @name = adjust_name(name) 20 | end 21 | 22 | private 23 | 24 | def adjust_name(name) 25 | parts_of_name = name.split '::' 26 | refactored_name = '' 27 | 28 | parts_of_name.each_with_index do |part, index| 29 | refactored_name << '/' if index.positive? 30 | refactored_name << change_to_snake_case(part) 31 | end 32 | 33 | refactored_name 34 | end 35 | 36 | def remove_word(word, word_to_delete = 'Controller') 37 | word = "#{word}del" if word.include?(word_to_delete) 38 | word.slice!("#{word_to_delete}del") 39 | word 40 | end 41 | 42 | def change_to_snake_case(name) 43 | parts_of_name = name.split(/(?=[A-Z])/) # Split at CamelCase 44 | refactored_name = '' 45 | 46 | parts_of_name.each_with_index do |part, index| 47 | part.downcase! 48 | refactored_name << '_' if index.positive? 49 | refactored_name << part 50 | end 51 | 52 | refactored_name 53 | end 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /lib/arpa/entities/role.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Entities 3 | class Role 4 | attr_reader :id, :name, :description, :created_at, :updated_at, :removed, 5 | :action_ids, :actions, :profiles 6 | 7 | def initialize(attrs = {}) 8 | attrs = attrs.with_indifferent_access 9 | 10 | @id = attrs[:id] 11 | @name = attrs[:name] 12 | @description = attrs[:description] 13 | @action_ids = default_value_to_nil_or_empty(attrs[:action_ids], []) 14 | @actions = default_value_to_nil_or_empty(attrs[:actions], []) 15 | @profiles = default_value_to_nil_or_empty(attrs[:profiles], []) 16 | @created_at = attrs[:created_at] 17 | @updated_at = attrs[:updated_at] 18 | @removed = default_value_to_nil_or_empty(attrs[:removed], false) 19 | end 20 | 21 | def has_profile? 22 | profiles.present? 23 | end 24 | 25 | private 26 | 27 | def default_value_to_nil_or_empty(attr_value, default_value) 28 | return attr_value if attr_value.present? 29 | default_value 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/arpa/exceptions/record_invalid.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Exceptions 3 | class RecordInvalid < StandardError 4 | attr_reader :errors 5 | 6 | def initialize(args) 7 | super(args[:message]) 8 | @errors = args[:errors] 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/arpa/repositories/actions/creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Actions 4 | class Creator 5 | include Arpa::Repositories::Registrator 6 | 7 | def mapper_instance 8 | Arpa::DataMappers::ActionMapper.instance 9 | end 10 | 11 | def repository_class 12 | RepositoryAction 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/arpa/repositories/actions/finder.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Actions 4 | class Finder 5 | include Arpa::Repositories::Base 6 | 7 | def by_name_and_resource(name, resource_id) 8 | record = repository_class.find_by(name: name, repository_resource_id: resource_id) 9 | mapper_instance.map_to_entity(record) if record 10 | end 11 | 12 | def permission(resource_name, action_name, profile_ids) 13 | record = repository_class 14 | .distinct(true) 15 | .joins(:resource, roles: :profiles) 16 | .find_by(repository_profiles: { id: profile_ids }, 17 | repository_resources: { name: resource_name }, 18 | name: action_name) 19 | mapper_instance.map_to_entity(record) if record 20 | end 21 | 22 | def mapper_instance 23 | Arpa::DataMappers::ActionMapper.instance 24 | end 25 | 26 | def repository_class 27 | RepositoryAction 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/arpa/repositories/actions/remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Actions 4 | class Remover 5 | include Arpa::Repositories::Base 6 | 7 | def destroy(entity) 8 | repository_class.destroy(entity.id) 9 | end 10 | 11 | def mapper_instance 12 | Arpa::DataMappers::ActionMapper.instance 13 | end 14 | 15 | def repository_class 16 | RepositoryAction 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/repositories/actions/repository_action.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Actions 4 | class RepositoryAction < ActiveRecord::Base 5 | default_scope { order(name: :asc) } 6 | 7 | alias_attribute :resource_id, :repository_resource_id 8 | belongs_to :resource, foreign_key: 'repository_resource_id', class_name: 'Arpa::Repositories::Resources::RepositoryResource' 9 | 10 | has_and_belongs_to_many :roles, class_name: 'Arpa::Repositories::Roles::RepositoryRole' 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/arpa/repositories/base.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Base 4 | def mapper_instance 5 | raise NotImplementedError, "This #{self.class} cannot respond :mapper_instance" 6 | end 7 | 8 | def repository_class 9 | raise NotImplementedError, "This #{self.class} cannot respond :repository_class" 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/arpa/repositories/profiles/creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Profiles 4 | class Creator 5 | include Arpa::Repositories::Registrator 6 | 7 | def mapper_instance 8 | Arpa::DataMappers::ProfileMapper.instance 9 | end 10 | 11 | def repository_class 12 | RepositoryProfile 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/arpa/repositories/profiles/finder.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Profiles 4 | class Finder 5 | include Arpa::Repositories::Base 6 | 7 | def find(id) 8 | record = repository_class.find(id) 9 | mapper_instance.map_to_entity(record) 10 | end 11 | 12 | def all 13 | repository_class.all.collect do |record| 14 | mapper_instance.map_to_entity(record) 15 | end 16 | end 17 | 18 | def all_by_entity(entity_id, entity_class) 19 | repository_class 20 | .where("( (entity_id is null AND entity_class is null) OR (entity_id = '#{entity_id}' AND entity_class = '#{entity_class}') )") 21 | .collect do |record| 22 | mapper_instance.map_to_entity(record) 23 | end 24 | end 25 | 26 | def mapper_instance 27 | Arpa::DataMappers::ProfileMapper.instance 28 | end 29 | 30 | def repository_class 31 | RepositoryProfile 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/arpa/repositories/profiles/remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Profiles 4 | class Remover 5 | include Arpa::Repositories::Base 6 | 7 | def destroy(entity) 8 | repository_class.destroy(entity.id) 9 | end 10 | 11 | def disable(entity) 12 | record = mapper_instance.map_to_record(entity) 13 | repository_class.update(record.id, removed: true) 14 | record.reload 15 | mapper_instance.map_to_entity(record) 16 | end 17 | 18 | def mapper_instance 19 | Arpa::DataMappers::ProfileMapper.instance 20 | end 21 | 22 | def repository_class 23 | RepositoryProfile 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/arpa/repositories/profiles/repository_profile.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Profiles 4 | class RepositoryProfile < ActiveRecord::Base 5 | default_scope { where(removed: false).order(name: :asc) } 6 | 7 | has_and_belongs_to_many :roles, class_name: 'Arpa::Repositories::Roles::RepositoryRole' 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/arpa/repositories/profiles/updater.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Profiles 4 | class Updater 5 | include Arpa::Repositories::Registrator 6 | 7 | def post_update(entity, record) 8 | record.role_ids = entity.role_ids 9 | record.save! 10 | end 11 | 12 | def mapper_instance 13 | Arpa::DataMappers::ProfileMapper.instance 14 | end 15 | 16 | def repository_class 17 | RepositoryProfile 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/arpa/repositories/registrator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Registrator 4 | include Base 5 | 6 | def create(entity) 7 | save(entity, &:save!) 8 | end 9 | 10 | def update(entity) 11 | save(entity) do |record| 12 | record.updated_at = Time.new.utc 13 | attributes = record.attributes.except('id', 'created_at') 14 | 15 | repository_class.update(entity.id, attributes) 16 | 17 | record.reload 18 | record.reload 19 | post_update(entity, record) 20 | end 21 | end 22 | 23 | private 24 | 25 | def save(entity) 26 | record = mapper_instance.map_to_record(entity) 27 | begin 28 | yield(record) 29 | rescue ActiveRecord::RecordInvalid => invalid 30 | raise Arpa::Exceptions::RecordInvalid.new(message: invalid.message, errors: invalid.record.errors) 31 | end 32 | 33 | mapper_instance.map_to_entity(record) 34 | end 35 | 36 | def post_update(entity, record); end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/arpa/repositories/resources/creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Resources 4 | class Creator 5 | include Arpa::Repositories::Registrator 6 | 7 | def mapper_instance 8 | Arpa::DataMappers::ResourceMapper.instance 9 | end 10 | 11 | def repository_class 12 | RepositoryResource 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/arpa/repositories/resources/finder.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Resources 4 | class Finder 5 | include Arpa::Repositories::Base 6 | 7 | def find(id) 8 | record = repository_class.find(id) 9 | mapper_instance.map_to_entity(record) 10 | end 11 | 12 | def all 13 | repository_class.all.collect do |record| 14 | mapper_instance.map_to_entity(record) 15 | end 16 | end 17 | 18 | def by_full_name(full_name) 19 | record = repository_class.where(full_name: full_name).first 20 | mapper_instance.map_to_entity(record) if record 21 | end 22 | 23 | def mapper_instance 24 | Arpa::DataMappers::ResourceMapper.instance 25 | end 26 | 27 | def repository_class 28 | RepositoryResource 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/arpa/repositories/resources/remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Resources 4 | class Remover 5 | include Arpa::Repositories::Base 6 | 7 | def destroy(entity) 8 | repository_class.destroy(entity.id) 9 | end 10 | 11 | def mapper_instance 12 | Arpa::DataMappers::ResourceMapper.instance 13 | end 14 | 15 | def repository_class 16 | RepositoryResource 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/repositories/resources/repository_resource.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Resources 4 | class RepositoryResource < ActiveRecord::Base 5 | default_scope { order(name: :asc) } 6 | 7 | has_many :actions, dependent: :destroy, class_name: 'Arpa::Repositories::Actions::RepositoryAction' 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/arpa/repositories/roles/creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Roles 4 | class Creator 5 | include Arpa::Repositories::Registrator 6 | 7 | def mapper_instance 8 | Arpa::DataMappers::RoleMapper.instance 9 | end 10 | 11 | def repository_class 12 | RepositoryRole 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/arpa/repositories/roles/finder.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Roles 4 | class Finder 5 | include Arpa::Repositories::Base 6 | 7 | def find(id) 8 | record = repository_class.find(id) 9 | mapper_instance.map_to_entity(record) 10 | end 11 | 12 | def all 13 | repository_class.all.collect do |record| 14 | mapper_instance.map_to_entity(record) 15 | end 16 | end 17 | 18 | def mapper_instance 19 | Arpa::DataMappers::RoleMapper.instance 20 | end 21 | 22 | def repository_class 23 | RepositoryRole 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/arpa/repositories/roles/remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Roles 4 | class Remover 5 | include Arpa::Repositories::Base 6 | 7 | def destroy(entity) 8 | repository_class.destroy(entity.id) 9 | end 10 | 11 | def disable(entity) 12 | record = mapper_instance.map_to_record(entity) 13 | repository_class.update(record.id, removed: true) 14 | record.reload 15 | mapper_instance.map_to_entity(record) 16 | end 17 | 18 | def mapper_instance 19 | Arpa::DataMappers::RoleMapper.instance 20 | end 21 | 22 | def repository_class 23 | RepositoryRole 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/arpa/repositories/roles/repository_role.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Roles 4 | class RepositoryRole < ActiveRecord::Base 5 | default_scope { where(removed: false).order(name: :asc) } 6 | 7 | has_and_belongs_to_many :actions, class_name: 'Arpa::Repositories::Actions::RepositoryAction' 8 | has_and_belongs_to_many :profiles, class_name: 'Arpa::Repositories::Profiles::RepositoryProfile' 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/arpa/repositories/roles/updater.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Repositories 3 | module Roles 4 | class Updater 5 | include Arpa::Repositories::Registrator 6 | 7 | def post_update(entity, record) 8 | record.action_ids = entity.action_ids 9 | record.save! 10 | end 11 | 12 | def mapper_instance 13 | Arpa::DataMappers::RoleMapper.instance 14 | end 15 | 16 | def repository_class 17 | RepositoryRole 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/arpa/services/actions/create/action_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Actions 4 | module Create 5 | class ActionCreator 6 | def create_many(params) 7 | params[:actions_names].collect do |action_name| 8 | create(action_params(params, action_name)) 9 | end 10 | end 11 | 12 | def create(params) 13 | action = action_instance(params) 14 | 15 | action_found = finder_repo.by_name_and_resource(params[:name], params[:resource_id]) 16 | return action_found if action_found 17 | 18 | validate_action(action) 19 | creator_repo.create(action) 20 | end 21 | 22 | private 23 | 24 | def action_params(params, action_name) 25 | { name: action_name, resource_id: params[:resource].id } 26 | end 27 | 28 | def action_instance(params) 29 | Arpa::Entities::Action.new(params) 30 | end 31 | 32 | def validate_action(action) 33 | validator = Arpa::Validators::ActionValidator.new(action) 34 | raise Arpa::Exceptions::RecordInvalid.new(message: validator.errors.messages, errors: validator.errors) unless validator.valid? 35 | end 36 | 37 | def finder_repo 38 | @finder_repo ||= Arpa::Repositories::Actions::Finder.new 39 | end 40 | 41 | def creator_repo 42 | @creator_repo ||= Arpa::Repositories::Actions::Creator.new 43 | end 44 | end 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/arpa/services/actions/remove/action_remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Actions 4 | module Remove 5 | class ActionRemover 6 | def remove_nonexistent_actions(params) 7 | params[:resource].actions.each do |action| 8 | exist = params[:actions_names].include?(action.name) 9 | remover_repo.destroy(action) unless exist 10 | end 11 | end 12 | 13 | private 14 | 15 | def remover_repo 16 | @remover_repo ||= Arpa::Repositories::Actions::Remover.new 17 | end 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/arpa/services/base.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Base 4 | def self.included(base) 5 | base.extend ClassMethods 6 | end 7 | 8 | def manager_action(callback) 9 | begin_transaction do 10 | result = yield 11 | callback[:success].call result 12 | rescue StandardError => e 13 | callback[:fail].call e 14 | end 15 | end 16 | 17 | private 18 | 19 | def begin_transaction 20 | self.class._repository_transaction.transaction do 21 | yield 22 | end 23 | end 24 | 25 | module ClassMethods 26 | def repository_transaction(repository_transaction_class) 27 | @repository_transaction = repository_transaction_class 28 | end 29 | 30 | def _repository_transaction 31 | @repository_transaction ||= 'ActiveRecord::Base' 32 | @repository_transaction.constantize 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/arpa/services/profiles/create/profile_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Profiles 4 | module Create 5 | class ProfileCreator 6 | def create(params) 7 | profile = profile_instance(params) 8 | validate_profile(profile) 9 | creator_repo.create(profile) 10 | end 11 | 12 | private 13 | 14 | def profile_instance(params) 15 | Arpa::Entities::Profile.new(params) 16 | end 17 | 18 | def validate_profile(profile) 19 | validator = Arpa::Validators::ProfileValidator.new(profile) 20 | raise Arpa::Exceptions::RecordInvalid.new(message: validator.errors.messages, errors: validator.errors) unless validator.valid? 21 | end 22 | 23 | def creator_repo 24 | @creator_repo ||= Arpa::Repositories::Profiles::Creator.new 25 | end 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/arpa/services/profiles/profile_manager_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Profiles 4 | class ProfileManagerCreator 5 | include Arpa::Services::Base 6 | 7 | def create(params, callback) 8 | manager_action callback do 9 | profile_creator.create(params[:profile]) 10 | end 11 | end 12 | 13 | private 14 | 15 | def profile_creator 16 | @profile_creator ||= Arpa::Services::Profiles::Create::ProfileCreator.new 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/services/profiles/profile_manager_remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Profiles 4 | class ProfileManagerRemover 5 | include Arpa::Services::Base 6 | 7 | def remove(params, callback) 8 | manager_action callback do 9 | role = params[:profile] 10 | disable = params[:disable] 11 | profile_remover.remove(role, disable) 12 | end 13 | end 14 | 15 | private 16 | 17 | def profile_remover 18 | @profile_remover ||= Arpa::Services::Profiles::Remove::ProfileRemover.new 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/arpa/services/profiles/profile_manager_updater.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Profiles 4 | class ProfileManagerUpdater 5 | include Arpa::Services::Base 6 | 7 | def update(params, callback) 8 | manager_action callback do 9 | profile_updater.update(params[:profile]) 10 | end 11 | end 12 | 13 | private 14 | 15 | def profile_updater 16 | @profile_updater ||= Arpa::Services::Profiles::Update::ProfileUpdater.new 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/services/profiles/remove/profile_remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Profiles 4 | module Remove 5 | class ProfileRemover 6 | def remove(entity, disable = false) 7 | if disable 8 | remover_repo.disable(entity) 9 | else 10 | remover_repo.destroy(entity) 11 | end 12 | end 13 | 14 | private 15 | 16 | def remover_repo 17 | @remover_repo ||= Arpa::Repositories::Profiles::Remover.new 18 | end 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/arpa/services/profiles/update/profile_updater.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Profiles 4 | module Update 5 | class ProfileUpdater 6 | def update(params) 7 | profile = profile_instance(params) 8 | validate_profile(profile) 9 | updater_repo.update(profile) 10 | end 11 | 12 | private 13 | 14 | def profile_instance(params) 15 | Arpa::Entities::Profile.new(params) 16 | end 17 | 18 | def validate_profile(profile) 19 | validator = Arpa::Validators::ProfileValidator.new(profile) 20 | raise Arpa::Exceptions::RecordInvalid.new(message: validator.errors.messages, errors: validator.errors) unless validator.valid? 21 | end 22 | 23 | def updater_repo 24 | @updater_repo ||= Arpa::Repositories::Profiles::Updater.new 25 | end 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/arpa/services/resources/create/resource_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Resources 4 | module Create 5 | class ResourceCreator 6 | def create(resourceable) 7 | resource = resource_instance(resourceable) 8 | 9 | resource_found = finder_repo.by_full_name(resource.full_name) 10 | return resource_found if resource_found 11 | 12 | validate_resource(resource) 13 | creator_repo.create(resource) 14 | end 15 | 16 | private 17 | 18 | def resource_instance(resourceable) 19 | resource = Arpa::Entities::Resource.new(full_name: resourceable.to_s) 20 | resource.build_correct_name 21 | resource 22 | end 23 | 24 | def validate_resource(resource) 25 | validator = Arpa::Validators::ResourceValidator.new(resource) 26 | raise Arpa::Exceptions::RecordInvalid.new(message: validator.errors.messages, errors: validator.errors) unless validator.valid? 27 | end 28 | 29 | def finder_repo 30 | @finder_repo ||= Arpa::Repositories::Resources::Finder.new 31 | end 32 | 33 | def creator_repo 34 | @creator_repo ||= Arpa::Repositories::Resources::Creator.new 35 | end 36 | end 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/arpa/services/resources/remove/resource_remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Resources 4 | module Remove 5 | class ResourceRemover 6 | def remove_nonexistent_resources(resourceables) 7 | resourceables_names = resourceables.map(&:to_s) 8 | 9 | finder_repo.all.each do |resource| 10 | exist = resourceables_names.include?(resource.full_name) 11 | remover_repo.destroy(resource) unless exist 12 | end 13 | end 14 | 15 | private 16 | 17 | def finder_repo 18 | @finder_repo ||= Arpa::Repositories::Resources::Finder.new 19 | end 20 | 21 | def remover_repo 22 | @remover_repo ||= Arpa::Repositories::Resources::Remover.new 23 | end 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/arpa/services/resources/resource_manager_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Resources 4 | class ResourceManagerCreator 5 | include Arpa::Services::Base 6 | 7 | def create(params, callback) 8 | manager_action callback do 9 | resourceables = params[:resourceables] 10 | except_action_methods = params[:except_action_methods] || [] 11 | 12 | resource_remover.remove_nonexistent_resources(resourceables) 13 | 14 | resourceables.collect do |resourceable| 15 | resource = resource_creator.create(resourceable) 16 | action_params = action_params(resource, resourceable, except_action_methods) 17 | 18 | action_remover.remove_nonexistent_actions(action_params) 19 | action_creator.create_many(action_params) 20 | 21 | resource 22 | end 23 | end 24 | end 25 | 26 | private 27 | 28 | def resource_remover 29 | @resource_remover ||= Arpa::Services::Resources::Remove::ResourceRemover.new 30 | end 31 | 32 | def action_remover 33 | @action_remover ||= Arpa::Services::Actions::Remove::ActionRemover.new 34 | end 35 | 36 | def resource_creator 37 | @resource_creator ||= Arpa::Services::Resources::Create::ResourceCreator.new 38 | end 39 | 40 | def action_creator 41 | @action_creator ||= Arpa::Services::Actions::Create::ActionCreator.new 42 | end 43 | 44 | def action_params(resource, resourceable, except_action_methods) 45 | actions_names = resourceable.action_methods.reject { |action| except_action_methods.include?(action) } 46 | { resource: resource, actions_names: actions_names } 47 | end 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /lib/arpa/services/roles/create/role_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Roles 4 | module Create 5 | class RoleCreator 6 | def create(params) 7 | role = role_instance(params) 8 | validate_role(role) 9 | creator_repo.create(role) 10 | end 11 | 12 | private 13 | 14 | def role_instance(params) 15 | Arpa::Entities::Role.new(params) 16 | end 17 | 18 | def validate_role(role) 19 | validator = Arpa::Validators::RoleValidator.new(role) 20 | raise Arpa::Exceptions::RecordInvalid.new(message: validator.errors.messages, errors: validator.errors) unless validator.valid? 21 | end 22 | 23 | def creator_repo 24 | @creator_repo ||= Arpa::Repositories::Roles::Creator.new 25 | end 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/arpa/services/roles/remove/role_remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Roles 4 | module Remove 5 | class RoleRemover 6 | def remove(entity) 7 | if entity.has_profile? 8 | remover_repo.disable(entity) 9 | else 10 | remover_repo.destroy(entity) 11 | end 12 | end 13 | 14 | private 15 | 16 | def remover_repo 17 | @remover_repo ||= Arpa::Repositories::Roles::Remover.new 18 | end 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/arpa/services/roles/role_manager_creator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Roles 4 | class RoleManagerCreator 5 | include Arpa::Services::Base 6 | 7 | def create(params, callback) 8 | manager_action callback do 9 | role_creator.create(params[:role]) 10 | end 11 | end 12 | 13 | private 14 | 15 | def role_creator 16 | @role_creator ||= Arpa::Services::Roles::Create::RoleCreator.new 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/services/roles/role_manager_remover.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Roles 4 | class RoleManagerRemover 5 | include Arpa::Services::Base 6 | 7 | def remove(params, callback) 8 | manager_action callback do 9 | role = params[:role] 10 | role_remover.remove(role) 11 | end 12 | end 13 | 14 | private 15 | 16 | def role_remover 17 | @role_remover ||= Arpa::Services::Roles::Remove::RoleRemover.new 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/arpa/services/roles/role_manager_updater.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Roles 4 | class RoleManagerUpdater 5 | include Arpa::Services::Base 6 | 7 | def update(params, callback) 8 | manager_action callback do 9 | role_updater.update(params[:role]) 10 | end 11 | end 12 | 13 | private 14 | 15 | def role_updater 16 | @role_updater ||= Arpa::Services::Roles::Update::RoleUpdater.new 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/services/roles/update/role_updater.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | module Roles 4 | module Update 5 | class RoleUpdater 6 | def update(params) 7 | role = role_instance(params) 8 | validate_role(role) 9 | updater_repo.update(role) 10 | end 11 | 12 | private 13 | 14 | def role_instance(params) 15 | Arpa::Entities::Role.new(params) 16 | end 17 | 18 | def validate_role(role) 19 | validator = Arpa::Validators::RoleValidator.new(role) 20 | raise Arpa::Exceptions::RecordInvalid.new(message: validator.errors.messages, errors: validator.errors) unless validator.valid? 21 | end 22 | 23 | def updater_repo 24 | @updater_repo ||= Arpa::Repositories::Roles::Updater.new 25 | end 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/arpa/services/verifier.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Services 3 | class Verifier 4 | def initialize(current_user) 5 | @current_user = current_user 6 | end 7 | 8 | def has_access?(resource, action) 9 | free_access_action = action.to_s.split('_')[0] 10 | return true if @current_user.is_arpa_admin? || free_access_action.empty? 11 | action_finder.permission(resource.to_s, action.to_s, @current_user.profile_ids) 12 | end 13 | 14 | private 15 | 16 | def action_finder 17 | @action_finder ||= Arpa::Repositories::Actions::Finder.new 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/arpa/validators/action_validator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Validators 3 | class ActionValidator 4 | include ActiveModel::Validations 5 | 6 | attr_reader :name, :resource_id 7 | 8 | validates :name, :resource_id, presence: true 9 | 10 | def initialize(action) 11 | @name = action.name 12 | @resource_id = action.resource_id 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/arpa/validators/profile_validator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Validators 3 | class ProfileValidator 4 | include ActiveModel::Validations 5 | 6 | attr_reader :name, :description, :role_ids 7 | 8 | validates :name, :description, presence: true 9 | validates :role_ids, presence: { message: :many_blank } 10 | 11 | def initialize(profile) 12 | @name = profile.name 13 | @description = profile.description 14 | @role_ids = profile.role_ids 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/arpa/validators/resource_validator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Validators 3 | class ResourceValidator 4 | include ActiveModel::Validations 5 | 6 | attr_reader :full_name, :name 7 | 8 | validates :full_name, :name, presence: true 9 | 10 | def initialize(resource) 11 | @full_name = resource.full_name 12 | @name = resource.name 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/arpa/validators/role_validator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Validators 3 | class RoleValidator 4 | include ActiveModel::Validations 5 | 6 | attr_reader :name, :description, :action_ids 7 | 8 | validates :name, :description, presence: true 9 | validates :action_ids, presence: { message: :many_blank } 10 | 11 | def initialize(role) 12 | @name = role.name 13 | @description = role.description 14 | @action_ids = role.action_ids 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/arpa/version.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | VERSION = '0.3.0'.freeze 3 | end 4 | -------------------------------------------------------------------------------- /lib/config/locales/arpa.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | errors: 3 | format: ! '%{attribute} %{message}' 4 | messages: 5 | many_blank: 'you must select at least one' 6 | 7 | flash: 8 | actions: 9 | generate_resources_and_actions: 10 | notice: 'Resources have been successfully created' 11 | alert: 'Resources were not successfully created' 12 | create_role: 13 | notice: 'Role was successfully created' 14 | update_role: 15 | notice: 'Role was successfully updated' 16 | remove_role: 17 | notice: 'Role was successfully removed' 18 | alert: 'Fail when tried remove a Role' 19 | create_profile: 20 | notice: 'Profile was successfully created' 21 | update_profile: 22 | notice: 'Profile was successfully updated' 23 | remove_profile: 24 | notice: 'Profile was successfully removed' 25 | alert: 'Fail when tried remove a Profile' 26 | -------------------------------------------------------------------------------- /lib/generators/arpa/controllers_generator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Generators 3 | class ControllersGenerator < Rails::Generators::Base 4 | source_root File.expand_path('templates', __dir__) 5 | 6 | def copy_resources_views_files 7 | copy_file 'views/resources/index.html.erb', 'app/views/arpa/resources/index.html.erb' 8 | copy_file 'views/resources/show.html.erb', 'app/views/arpa/resources/show.html.erb' 9 | 10 | copy_file 'views/roles/index.html.erb', 'app/views/arpa/roles/index.html.erb' 11 | copy_file 'views/roles/show.html.erb', 'app/views/arpa/roles/show.html.erb' 12 | copy_file 'views/roles/new.html.erb', 'app/views/arpa/roles/new.html.erb' 13 | copy_file 'views/roles/edit.html.erb', 'app/views/arpa/roles/edit.html.erb' 14 | copy_file 'views/roles/_form.html.erb', 'app/views/arpa/roles/_form.html.erb' 15 | 16 | copy_file 'views/profiles/index.html.erb', 'app/views/arpa/profiles/index.html.erb' 17 | copy_file 'views/profiles/show.html.erb', 'app/views/arpa/profiles/show.html.erb' 18 | copy_file 'views/profiles/new.html.erb', 'app/views/arpa/profiles/new.html.erb' 19 | copy_file 'views/profiles/edit.html.erb', 'app/views/arpa/profiles/edit.html.erb' 20 | copy_file 'views/profiles/_form.html.erb', 'app/views/arpa/profiles/_form.html.erb' 21 | end 22 | 23 | def copy_stylesheet_files 24 | copy_file 'assets/stylesheets/arpa_accordion.scss', 'app/assets/stylesheets/arpa/arpa_accordion.scss' 25 | end 26 | 27 | def add_controllers 28 | copy_file 'controllers/resources_controller.rb', 'app/controllers/arpa/resources_controller.rb' 29 | copy_file 'controllers/roles_controller.rb', 'app/controllers/arpa/roles_controller.rb' 30 | copy_file 'controllers/profiles_controller.rb', 'app/controllers/arpa/profiles_controller.rb' 31 | end 32 | 33 | def add_routes 34 | route <<~RUBY 35 | scope module: :arpa do 36 | resources :resources do 37 | collection do 38 | get 'generate_resources_and_actions' 39 | end 40 | end 41 | 42 | resources :roles do 43 | collection do 44 | delete ':id', to: 'roles#remove' 45 | end 46 | end 47 | 48 | resources :profiles do 49 | collection do 50 | delete ':id', to: 'profiles#remove' 51 | end 52 | end 53 | end 54 | RUBY 55 | end 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/generators/arpa/install_generator.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | module Generators 3 | class InstallGenerator < Rails::Generators::Base 4 | include Rails::Generators::Migration 5 | 6 | source_root File.expand_path(__dir__) 7 | 8 | desc <<-DESC.strip_heredoc 9 | The Name of table to create the associate table. 10 | 11 | E.g. users, admins. 12 | 13 | By default is 'users' 14 | DESC 15 | 16 | argument :associate_table, required: false 17 | 18 | desc <<-DESC.strip_heredoc 19 | The Primary key to create the associate table. 20 | 21 | E.g. user_id, admin_id. 22 | 23 | By default is 'user_id' 24 | DESC 25 | argument :associate_primary_key, required: false 26 | 27 | def self.next_migration_number(dirname) 28 | return Time.new.utc.strftime('%Y%m%d%H%M%S') if ActiveRecord::Base.timestamped_migrations 29 | format('%.3d', (current_migration_number(dirname) + 1)) 30 | end 31 | 32 | desc 'Create a migrate file with all necessery tables including the associate table.' 33 | 34 | def create_migrate_files 35 | @associate_table ||= 'users' 36 | @associate_primary_key ||= "#{@associate_table.singularize}_id" 37 | migration_template 'templates/migration.rb', 'db/migrate/create_arpa_tables.rb' 38 | end 39 | 40 | def copy_locales 41 | copy_file '../../config/locales/arpa.en.yml', 'config/locales/arpa.en.yml' 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/assets/stylesheets/arpa_accordion.scss: -------------------------------------------------------------------------------- 1 | // ArpaAccordion 2 | .arpa-accordion { 3 | margin: 10px auto 30px auto; 4 | text-align: left; 5 | 6 | .arpa-accordion-title { 7 | position: relative; 8 | z-index: 20; 9 | display: block; 10 | padding: 10px 12px; 11 | cursor: pointer; 12 | color: #555; 13 | font-size: 18px; 14 | font-weight: bold; 15 | background: #fff; 16 | border: 1px solid #cfcfcf; 17 | 18 | &:hover{ 19 | background: #fff; 20 | } 21 | } 22 | 23 | .arpa-accordion-input { 24 | display: none; 25 | 26 | &:checked + .arpa-accordion-item { 27 | box-shadow: 3px 3px 3px red; 28 | } 29 | 30 | &:checked + .arpa-accordion-title, 31 | &:checked + .arpa-accordion-title:hover { 32 | margin-bottom: 0; 33 | border-bottom: none; 34 | } 35 | 36 | &:checked + .arpa-accordion-title { 37 | border-color: #bbb; 38 | 39 | &:after { 40 | background: none; 41 | } 42 | } 43 | 44 | &:checked ~ .arpa-accordion-content { 45 | padding: 10px 20px 0; 46 | margin-bottom: 10px; 47 | max-height: 9999999px; 48 | border: 1px solid #bbb; 49 | opacity: 1; 50 | } 51 | } 52 | 53 | .arpa-accordion-title { 54 | &:after { 55 | content: ''; 56 | position: absolute; 57 | width: 24px; 58 | height: 24px; 59 | right: 13px; 60 | top: 7px; 61 | // background: url(image-path("arpa-accordion-arrow.png")) -6px -6px; 62 | } 63 | 64 | &:hover { 65 | &:after { 66 | background-position: -6px -42px; 67 | } 68 | } 69 | } 70 | 71 | .arpa-accordion-content { 72 | z-index: 10; 73 | position: relative; 74 | padding: 0 20px; 75 | max-height: 0px; 76 | background: #fafafa; 77 | overflow: hidden; 78 | opacity: 0; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/controllers/profiles_controller.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | class ProfilesController < ApplicationController 3 | before_action :set_profile, only: %i[show edit update remove] 4 | 5 | # GET /profiles 6 | def index 7 | @profiles = profile_finder.all 8 | end 9 | 10 | # GET /profiles/1 11 | def show; end 12 | 13 | # GET /profiles/new 14 | def new 15 | @profile = Arpa::Entities::Profile.new 16 | all_roles 17 | end 18 | 19 | # GET /profiles/1/edit 20 | def edit 21 | all_roles 22 | end 23 | 24 | # POST /profiles 25 | def create 26 | profile_creator.create({ profile: profile_params }, 27 | success: redirect_to_index(I18n.t('flash.actions.create_profile.notice')), 28 | fail: render_errors(:new)) 29 | end 30 | 31 | # PATCH/PUT /profiles/1 32 | def update 33 | profile_updater.update({ profile: profile_params }, 34 | success: redirect_to_index(I18n.t('flash.actions.update_profile.notice')), 35 | fail: render_errors(:edit)) 36 | end 37 | 38 | # DELETE /profiles/1 39 | def remove 40 | profile_remover.remove({ profile: @profile }, 41 | success: redirect_to_index(I18n.t('flash.actions.remove_profile.notice')), 42 | fail: redirect_to_index(I18n.t('flash.actions.remove_profile.alert'))) 43 | end 44 | 45 | private 46 | 47 | def redirect_to_index(message) 48 | lambda do |profile| 49 | redirect_to profile_path(profile.id), notice: message 50 | end 51 | end 52 | 53 | def render_errors(action_to_render) 54 | lambda do |error| 55 | @profile = Arpa::Entities::Profile.new(profile_params) 56 | @error = error 57 | all_roles 58 | render action_to_render 59 | end 60 | end 61 | 62 | def profile_creator 63 | @profile_creator ||= Arpa::Services::Profiles::ProfileManagerCreator.new 64 | end 65 | 66 | def profile_updater 67 | @profile_updater ||= Arpa::Services::Profiles::ProfileManagerUpdater.new 68 | end 69 | 70 | def profile_remover 71 | @profile_remover ||= Arpa::Services::Profiles::ProfileManagerRemover.new 72 | end 73 | 74 | def profile_finder 75 | @profile_finder ||= Arpa::Repositories::Profiles::Finder.new 76 | end 77 | 78 | def role_finder 79 | @role_finder ||= Arpa::Repositories::Roles::Finder.new 80 | end 81 | 82 | def all_roles 83 | @roles = role_finder.all 84 | end 85 | 86 | def set_profile 87 | @profile = profile_finder.find(params[:id]) 88 | end 89 | 90 | def profile_params 91 | permitted_params = %i[id name description entity_id entity_class] 92 | 93 | params.require(:profile) 94 | .permit(permitted_params, role_ids: []) 95 | .to_h 96 | end 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/controllers/resources_controller.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | class ResourcesController < ApplicationController 3 | before_action :set_resource, only: [:show] 4 | 5 | # GET /resources 6 | def index 7 | @resources = resource_finder.all 8 | end 9 | 10 | # GET /resources/1 11 | def show; end 12 | 13 | # GET /generate_resources_and_actions 14 | def generate_resources_and_actions 15 | Rails.application.eager_load! 16 | 17 | resource_params = { 18 | resourceables: ApplicationController.descendants, 19 | except_action_methods: ApplicationController.action_methods 20 | } 21 | resource_creator.create(resource_params, 22 | success: success_callback, 23 | fail: fail_callback) 24 | 25 | redirect_to resources_path 26 | end 27 | 28 | private 29 | 30 | def success_callback 31 | lambda do |_resource| 32 | flash[:notice] = I18n.t('flash.actions.generate_resources_and_actions.notice') 33 | end 34 | end 35 | 36 | def fail_callback 37 | lambda do |_error| 38 | flash[:alert] = I18n.t('flash.actions.generate_resources_and_actions.alert') 39 | end 40 | end 41 | 42 | def resource_creator 43 | @resource_creator ||= Arpa::Services::Resources::ResourceManagerCreator.new 44 | end 45 | 46 | def resource_finder 47 | @resource_finder ||= Arpa::Repositories::Resources::Finder.new 48 | end 49 | 50 | def set_resource 51 | @resource = resource_finder.find(params[:id]) 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/controllers/roles_controller.rb: -------------------------------------------------------------------------------- 1 | module Arpa 2 | class RolesController < ApplicationController 3 | before_action :set_role, only: %i[show edit update remove] 4 | 5 | # GET /roles 6 | def index 7 | @roles = role_finder.all 8 | end 9 | 10 | # GET /roles/1 11 | def show; end 12 | 13 | # GET /roles/new 14 | def new 15 | @role = Arpa::Entities::Role.new 16 | all_resources 17 | end 18 | 19 | # GET /roles/1/edit 20 | def edit 21 | all_resources 22 | end 23 | 24 | # POST /roles 25 | def create 26 | role_creator.create({ role: role_params }, 27 | success: redirect_to_index(I18n.t('flash.actions.create_role.notice')), 28 | fail: render_errors(:new)) 29 | end 30 | 31 | # PATCH/PUT /roles/1 32 | def update 33 | role_updater.update({ role: role_params }, 34 | success: redirect_to_index(I18n.t('flash.actions.update_role.notice')), 35 | fail: render_errors(:edit)) 36 | end 37 | 38 | # DELETE /roles/1 39 | def remove 40 | role_remover.remove({ role: @role }, 41 | success: redirect_to_index(I18n.t('flash.actions.remove_role.notice')), 42 | fail: redirect_to_index(I18n.t('flash.actions.remove_role.alert'))) 43 | end 44 | 45 | private 46 | 47 | def redirect_to_index(message) 48 | lambda do |_role| 49 | redirect_to roles_path, notice: message 50 | end 51 | end 52 | 53 | def render_errors(action_to_render) 54 | lambda do |error| 55 | @role = Arpa::Entities::Role.new(role_params) 56 | @error = error 57 | all_resources 58 | render action_to_render 59 | end 60 | end 61 | 62 | def role_creator 63 | @role_creator ||= Arpa::Services::Roles::RoleManagerCreator.new 64 | end 65 | 66 | def role_updater 67 | @role_updater ||= Arpa::Services::Roles::RoleManagerUpdater.new 68 | end 69 | 70 | def role_remover 71 | @role_remover ||= Arpa::Services::Roles::RoleManagerRemover.new 72 | end 73 | 74 | def role_finder 75 | @role_finder ||= Arpa::Repositories::Roles::Finder.new 76 | end 77 | 78 | def resource_finder 79 | @resource_finder ||= Arpa::Repositories::Resources::Finder.new 80 | end 81 | 82 | def all_resources 83 | @resources = resource_finder.all 84 | end 85 | 86 | def set_role 87 | @role = role_finder.find(params[:id]) 88 | end 89 | 90 | def role_params 91 | permitted_params = %i[id name description] 92 | 93 | params.require(:role) 94 | .permit(permitted_params, action_ids: []) 95 | .to_h 96 | end 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/migration.rb: -------------------------------------------------------------------------------- 1 | class CreateArpaTables < ActiveRecord::Migration[5.2] 2 | def change 3 | 4 | create_table :repository_resources, :force => true do |t| 5 | t.string :name 6 | t.string :full_name 7 | t.timestamps null: false 8 | end 9 | 10 | create_table :repository_actions, :force => true do |t| 11 | t.string :name 12 | t.references :repository_resource, index: true 13 | t.timestamps null: false 14 | end 15 | 16 | add_foreign_key :repository_actions, :repository_resources 17 | 18 | create_table :repository_roles, :force => true do |t| 19 | t.string :name 20 | t.string :description 21 | t.boolean :removed, default: false 22 | t.timestamps null: false 23 | end 24 | 25 | create_join_table :repository_actions, :repository_roles, :force => true do |t| 26 | t.index :repository_action_id, name: 'action_role_id' 27 | t.index :repository_role_id, name: 'role_action_id' 28 | end 29 | 30 | create_table :repository_profiles, :force => true do |t| 31 | t.string :name 32 | t.string :description 33 | t.boolean :removed, default: false 34 | t.timestamps null: false 35 | end 36 | 37 | create_join_table :repository_roles, :repository_profiles, :force => true do |t| 38 | t.index :repository_role_id, name: 'role_profile_id' 39 | t.index :repository_profile_id, name: 'profile_role_ids' 40 | end 41 | 42 | create_join_table :repository_profiles, <%= ":#{@associate_table}" %>, :force => true do |t| 43 | t.index :repository_profile_id, name: 'profile_user_id' 44 | t.index <%= ":#{@associate_primary_key}" %>, name: 'user_profile_id' 45 | end 46 | 47 | add_column <%= ":#{@associate_table}" %>, :is_arpa_admin, :boolean, default: false 48 | 49 | add_column :repository_profiles, :entity_id, :integer, default: nil 50 | add_column :repository_profiles, :entity_class, :string, default: nil 51 | 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/profiles/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(:profile, url: {action: action}, method: method) do |f| %> 2 | <% if @error.present? && @error.errors.any? %> 3 |
4 |

<%= pluralize(@error.errors.count, "error") %> prohibited this user from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 | <%= f.hidden_field :id, value: @profile.id %> 15 | 16 |
17 | <%= f.label :name %>
18 | <%= f.text_field :name %> 19 |
20 | 21 |
22 | <%= f.label :description %>
23 | <%= f.text_field :description %> 24 |
25 | 26 |
27 | <%= f.label :entity_id %>
28 | <%= f.text_field :entity_id %> 29 |
30 | 31 |
32 | <%= f.label :entity_class %>
33 | <%= f.text_field :entity_class %> 34 |
35 | 36 |
37 | 38 | <% @roles.each do |role| %> 39 |
40 | > 41 | <%= "#{role.name} - #{role.description}"%> 42 |
43 | <% end %> 44 | 45 |
46 | 47 |
48 | <%= f.submit %> 49 |
50 | 51 | <% end %> 52 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/profiles/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Profile

2 | 3 | <%= render 'form', action: 'update', method: :patch %> 4 | 5 | <%= link_to 'Show', profile_path(@profile.id) %> | 6 | <%= link_to 'Back', profiles_path %> 7 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/profiles/index.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

Listing Profiles

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | <% @profiles.each do |profile| %> 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | <% end %> 28 | 29 |
NameDescriptionEntity IDEntity Class
<%= profile.name %><%= profile.description %><%= profile.entity_id %><%= profile.entity_class %><%= link_to 'Show', profile_path(profile.id) %><%= link_to 'Edit', edit_profile_path(profile.id) %><%= link_to 'Destroy', profile_path(profile.id), method: :delete, data: { confirm: 'Are you sure?' } %>
30 | 31 |
32 | 33 | <%= link_to 'New Profile', new_profile_path %> 34 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/profiles/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Profile

2 | 3 | <%= render 'form', action: 'create', method: :post %> 4 | 5 | <%= link_to 'Back', profiles_path %> 6 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/profiles/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @profile.name %> 6 |

7 | 8 |

9 | Description: 10 | <%= @profile.description %> 11 |

12 | 13 |

14 | Entity id: 15 | <%= @profile.entity_id %> 16 |

17 | 18 |

19 | Entity class: 20 | <%= @profile.entity_class %> 21 |

22 | 23 | 24 |
25 |
26 | List of Roles 27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | <% @profile.roles.each do |role| %> 39 | 40 | 41 | 42 | 43 | <% end %> 44 | 45 |
NameDescription
<%= role.name %><%= role.description %>
46 | 47 | <%= link_to 'Back', profiles_path %> 48 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/resources/index.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 |

<%= alert %>

3 | 4 | 5 |

Listing Resources

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% @resources.each do |resource| %> 17 | 18 | 19 | 20 | 21 | <% end %> 22 | 23 |
Name
<%= resource.name %><%= link_to 'Show', resource_path(resource.id) %>
24 | 25 |
26 | 27 | <%= link_to 'Generate All Resources', generate_resources_and_actions_resources_path %> 28 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/resources/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @resource.name %> 6 |

7 | 8 | 9 |
10 |
11 | List of Actions 12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | <% @resource.actions.each do |action| %> 24 | 25 | 26 | 27 | 28 | <% end %> 29 | 30 |
NameDescription
<%= action.name %><%= action.description %>
31 | 32 | 33 | <%= link_to 'Back', resources_path %> 34 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/roles/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(:role, url: {action: action}, method: method) do |f| %> 2 | <% if @error.present? && @error.errors.any? %> 3 |
4 |

<%= pluralize(@error.errors.count, "error") %> prohibited this user from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 | <%= f.hidden_field :id, value: @role.id %> 15 | 16 |
17 | <%= f.label :name %>
18 | <%= f.text_field :name %> 19 |
20 | 21 |
22 | <%= f.label :description %>
23 | <%= f.text_field :description %> 24 |
25 | 26 |
27 | 28 | <% @resources.each do |resource| %> 29 |
30 | 31 | 34 | 35 |
36 | <% resource.actions.each do |action| %> 37 |
38 | > 39 | <%= action.name%> 40 |
41 | 42 | <% end %> 43 |
44 | 45 |
46 | 47 | <% end %> 48 | 49 |
50 | 51 |
52 | <%= f.submit %> 53 |
54 | 55 | <% end %> 56 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/roles/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Role

2 | 3 | <%= render 'form', action: 'update', method: :patch %> 4 | 5 | <%= link_to 'Show', role_path(@role.id) %> | 6 | <%= link_to 'Back', roles_path %> 7 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/roles/index.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

Listing Roles

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% @roles.each do |role| %> 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | <% end %> 24 | 25 |
NameDescription
<%= role.name %><%= role.description %><%= link_to 'Show', role_path(role.id) %><%= link_to 'Edit', edit_role_path(role.id) %><%= link_to 'Destroy', role_path(role.id), method: :delete, data: { confirm: 'Are you sure?' } %>
26 | 27 |
28 | 29 | <%= link_to 'New Role', new_role_path %> 30 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/roles/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Role

2 | 3 | <%= render 'form', action: 'create', method: :post %> 4 | 5 | <%= link_to 'Back', roles_path %> 6 | -------------------------------------------------------------------------------- /lib/generators/arpa/templates/views/roles/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @role.name %> 6 |

7 | 8 |

9 | Description: 10 | <%= @role.description %> 11 |

12 | 13 | 14 |
15 |
16 | List of Actions 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | <% @role.actions.each do |action| %> 29 | 30 | 31 | 32 | 33 | <% end %> 34 | 35 |
NameDescription
<%= action.name %><%= action.description %>
36 | 37 | <%= link_to 'Back', roles_path %> 38 | -------------------------------------------------------------------------------- /spec/factories/repository_actions.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :repository_action, class: Arpa::Repositories::Actions::RepositoryAction do 3 | trait :index do 4 | name 'index' 5 | resource { FactoryBot.create(:repository_resource, :user) } 6 | end 7 | 8 | trait :show do 9 | name 'show' 10 | resource { FactoryBot.create(:repository_resource, :user) } 11 | end 12 | 13 | trait :with_complete_association do 14 | name 'index_new' 15 | resource { FactoryBot.create(:repository_resource, :user) } 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/factories/repository_profiles.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :repository_profile, class: Arpa::Repositories::Profiles::RepositoryProfile do 3 | name 'some_profile' 4 | description 'description_profile' 5 | 6 | trait :with_complete_association do 7 | roles { [FactoryBot.create(:repository_role, :with_complete_association)] } 8 | end 9 | 10 | trait :with_entity do 11 | entity_id { FactoryBot.create(:entity) } 12 | entity_class { FactoryBot.create(:entity).class.to_s } 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/factories/repository_resources.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :repository_resource, class: Arpa::Repositories::Resources::RepositoryResource do 3 | trait :user do 4 | full_name 'UsersController' 5 | name 'users' 6 | end 7 | 8 | trait :contact do 9 | full_name 'ContactsController' 10 | name 'contacts' 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/factories/repository_roles.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :repository_role, class: Arpa::Repositories::Roles::RepositoryRole do 3 | name 'some_role' 4 | description 'description_role' 5 | 6 | trait :with_complete_association do 7 | actions { [FactoryBot.create(:repository_action, :with_complete_association)] } 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/factories/repository_test.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :entity, class: TestRepository do 3 | name 'some entity' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/lib/arpa/additions/resource_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | class ResourceImplementation 4 | def self.helper_method(args); end 5 | include Arpa::Additions::Resource 6 | def session 7 | '' 8 | end 9 | 10 | def current_user 11 | '' 12 | end 13 | end 14 | 15 | describe Arpa::Additions::Resource, type: :addition, fast: true do 16 | let(:resource_implementation) { ResourceImplementation.new } 17 | 18 | let(:verifier) { double } 19 | let(:resource) { double } 20 | let(:action) { double } 21 | 22 | before do 23 | allow(Arpa::Services::Verifier).to receive(:new).and_return(verifier) 24 | setup 25 | end 26 | 27 | describe '#has_access?' do 28 | let(:setup) do 29 | allow(verifier).to receive(:has_access?) 30 | resource_implementation.has_access?(resource, action) 31 | end 32 | 33 | it 'should call :new from Arpa::Services::Verifier' do 34 | expect(Arpa::Services::Verifier).to have_received(:new).once 35 | end 36 | 37 | it 'verifier should call :has_access? with resource and action as parameter' do 38 | expect(verifier).to have_received(:has_access?).with(resource, action).once 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/lib/arpa/data_mappers/action_mapper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::DataMappers::ActionMapper, type: :mapper, fast: true do 4 | let(:mapper) { Arpa::DataMappers::ActionMapper.instance } 5 | 6 | describe 'mapping to record instance' do 7 | let(:entity) { Arpa::Entities::Action.new(name: 'index', resource_id: 1) } 8 | let(:record_instance) { mapper.map_to_record(entity) } 9 | 10 | it 'record_instance should be an instance of ActiveRecord::Base' do 11 | expect(record_instance).to be_a ActiveRecord::Base 12 | end 13 | 14 | it 'record_instance should fill the property :name from entity property' do 15 | expect(record_instance.name).to eql 'index' 16 | end 17 | 18 | it 'record_instance should fill the property :resource_id and :repository_resource_id from entity property' do 19 | expect(record_instance.resource_id).to be == 1 20 | expect(record_instance.repository_resource_id).to be == 1 21 | end 22 | end 23 | 24 | describe 'mapping to entity instance' do 25 | let(:record) { create :repository_action, :index } 26 | let(:entity_instance) { mapper.map_to_entity(record) } 27 | 28 | it 'entity_instance should fill the property :name from record property' do 29 | expect(entity_instance.name).to eql 'index' 30 | end 31 | 32 | it 'entity_instance should fill the property :id from record property' do 33 | expect(entity_instance.id).to be == record.id 34 | end 35 | 36 | it 'entity_instance should fill the property :resource_id from record property' do 37 | expect(entity_instance.resource_id).to be == record.resource_id 38 | end 39 | 40 | it 'entity_instance should fill the property :resource from record property' do 41 | expect(entity_instance.resource).to be_an Arpa::Entities::Resource 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /spec/lib/arpa/data_mappers/base_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | class TestMapper < Arpa::DataMappers::Base 4 | entity_class 'TestRepository' 5 | repository_class 'TestRepository' 6 | attributes_to_map :id, :name 7 | end 8 | 9 | describe Arpa::DataMappers::Base, type: :mapper, fast: true do 10 | let(:mapper) { TestMapper.instance } 11 | 12 | context 'when initialize more than one Mapper' do 13 | let(:mapper_002) { TestMapper.instance } 14 | 15 | it 'the instances should use singleton pattern' do 16 | expect(mapper).to eq mapper_002 17 | end 18 | end 19 | 20 | describe 'mapping to record instance' do 21 | let(:entity) { double id: nil, name: 'Some Name' } 22 | let(:record_instance) { mapper.map_to_record(entity) } 23 | 24 | it 'record_instance should be an instance of ActiveRecord::Base' do 25 | expect(record_instance).to be_a ActiveRecord::Base 26 | end 27 | 28 | it 'record_instance should fill the property :name from entity property' do 29 | expect(record_instance.name).to eql 'Some Name' 30 | end 31 | end 32 | 33 | describe 'mapping to entity instance' do 34 | let(:record) { TestRepository.create(name: 'Name One') } 35 | let(:entity_instance) { mapper.map_to_entity(record) } 36 | 37 | it 'entity_instance should fill the property :name from record property' do 38 | expect(entity_instance.name).to eql 'Name One' 39 | end 40 | 41 | it 'entity_instance should fill the property :id from record property' do 42 | expect(entity_instance.id).to be == record.id 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/lib/arpa/data_mappers/profile_mapper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::DataMappers::ProfileMapper, type: :mapper, fast: true do 4 | let(:mapper) { Arpa::DataMappers::ProfileMapper.instance } 5 | 6 | describe 'mapping to record instance' do 7 | let(:entity) { Arpa::Entities::Profile.new(name: 'some_profile') } 8 | let(:record_instance) { mapper.map_to_record(entity) } 9 | 10 | it 'record_instance should be an instance of Arpa::Repositories::Profiles::RepositoryProfile' do 11 | expect(record_instance).to be_a Arpa::Repositories::Profiles::RepositoryProfile 12 | end 13 | 14 | it 'record_instance should fill the property :name from entity property' do 15 | expect(record_instance.name).to eql 'some_profile' 16 | end 17 | end 18 | 19 | describe 'mapping to entity instance' do 20 | let(:action_record) { create :repository_action, :index } 21 | let(:role_record) { create :repository_role, action_ids: [action_record.id] } 22 | let(:record) { create :repository_profile, role_ids: [role_record.id] } 23 | let(:entity_instance) { mapper.map_to_entity(record) } 24 | 25 | it 'entity_instance should fill the property :name from record property' do 26 | expect(entity_instance.name).to eql 'some_profile' 27 | end 28 | 29 | it 'entity_instance should fill the property :id from record property' do 30 | expect(entity_instance.id).to be == record.id 31 | end 32 | 33 | it 'entity_instance should fill the property :roles from record property' do 34 | expect(entity_instance.roles.first).to be_an Arpa::Entities::Role 35 | end 36 | 37 | it 'entity_instance should fill the property :role_ids from record property' do 38 | expect(entity_instance.role_ids).to eq [role_record.id] 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/lib/arpa/data_mappers/resource_mapper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::DataMappers::ResourceMapper, type: :mapper, fast: true do 4 | let(:mapper) { Arpa::DataMappers::ResourceMapper.instance } 5 | 6 | describe 'mapping to record instance' do 7 | let(:entity) { Arpa::Entities::Resource.new(full_name: 'UsersController') } 8 | let(:record_instance) { mapper.map_to_record(entity) } 9 | 10 | it 'record_instance should be an instance of ActiveRecord::Base' do 11 | expect(record_instance).to be_a ActiveRecord::Base 12 | end 13 | 14 | it 'record_instance should fill the property :name from entity property' do 15 | expect(record_instance.full_name).to eql 'UsersController' 16 | end 17 | end 18 | 19 | describe 'mapping to entity instance' do 20 | let(:action_record) { create :repository_action, :index } 21 | let(:record) { create :repository_resource, :user, actions: [action_record] } 22 | let(:entity_instance) { mapper.map_to_entity(record.reload) } 23 | 24 | it 'entity_instance should fill the property :name from record property' do 25 | expect(entity_instance.full_name).to eql 'UsersController' 26 | end 27 | 28 | it 'entity_instance should fill the property :id from record property' do 29 | expect(entity_instance.id).to be == record.id 30 | end 31 | 32 | it 'entity_instance should fill the property :actions from record property' do 33 | expect(entity_instance.actions.first).to be_an Arpa::Entities::Action 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/lib/arpa/data_mappers/role_mapper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::DataMappers::RoleMapper, type: :mapper, fast: true do 4 | let(:mapper) { Arpa::DataMappers::RoleMapper.instance } 5 | 6 | describe 'mapping to record instance' do 7 | let(:entity) { Arpa::Entities::Role.new(name: 'some_role') } 8 | let(:record_instance) { mapper.map_to_record(entity) } 9 | 10 | it 'record_instance should be an instance of Arpa::Repositories::Roles::RepositoryRole' do 11 | expect(record_instance).to be_a Arpa::Repositories::Roles::RepositoryRole 12 | end 13 | 14 | it 'record_instance should fill the property :name from entity property' do 15 | expect(record_instance.name).to eql 'some_role' 16 | end 17 | end 18 | 19 | describe 'mapping to entity instance' do 20 | let(:action_record) { create :repository_action, :index } 21 | let(:profile_record) { create :repository_profile } 22 | let(:record) { create :repository_role, profile_ids: [profile_record.id], action_ids: [action_record.id] } 23 | let(:entity_instance) { mapper.map_to_entity(record) } 24 | 25 | it 'entity_instance should fill the property :name from record property' do 26 | expect(entity_instance.name).to eql 'some_role' 27 | end 28 | 29 | it 'entity_instance should fill the property :id from record property' do 30 | expect(entity_instance.id).to be == record.id 31 | end 32 | 33 | it 'entity_instance should fill the property :actions from record property' do 34 | expect(entity_instance.actions.first).to be_an Arpa::Entities::Action 35 | end 36 | 37 | it 'entity_instance should fill the property :action_ids from record property' do 38 | expect(entity_instance.action_ids).to eq [action_record.id] 39 | end 40 | 41 | it 'entity_instance should fill the property :profiles from record property' do 42 | expect(entity_instance.profiles.first).to be_an Arpa::Entities::Profile 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/lib/arpa/entities/action_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Entities::Action, type: :entity, fast: true do 4 | subject { Arpa::Entities::Action.new resource: resource, name: 'index' } 5 | 6 | describe 'getting description by action name and resource name' do 7 | before do 8 | I18n.backend.store_translations(:en, entities: { resources: { users: { actions: { description: { index: 'List of Users' } } } } }) 9 | end 10 | 11 | context 'when resource.name is "users" and action.name is "index"' do 12 | let(:resource) { double(name: 'users') } 13 | 14 | it 'description should be "List of Users"' do 15 | expect(subject.description).to eql 'List of Users' 16 | end 17 | end 18 | end 19 | 20 | describe 'getting the resource name' do 21 | context 'when resource is not nil' do 22 | let(:resource) { double(name: 'users') } 23 | 24 | it 'resource name should be the same of the attribute' do 25 | expect(subject.resource_name).to eql 'users' 26 | end 27 | end 28 | 29 | context 'when resource is nil' do 30 | let(:resource) { nil } 31 | it 'resource name should be empty' do 32 | expect(subject.resource_name).to be_empty 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/lib/arpa/entities/profile_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Entities::Profile, type: :entity, fast: true do 4 | describe 'initializing' do 5 | describe 'setting default values' do 6 | context 'when pass some parameters as nil' do 7 | it 'attribute :role_ids should be an empty Array' do 8 | expect(subject.role_ids).to eq [] 9 | end 10 | 11 | it 'attribute :role should be an empty Array' do 12 | expect(subject.roles).to eq [] 13 | end 14 | 15 | it 'attribute :removed should be false' do 16 | expect(subject.removed).to be_falsey 17 | end 18 | end 19 | end 20 | 21 | context 'when pass some parameters as empty' do 22 | let(:attrs) { { role_ids: '', roles: '', removed: '' } } 23 | subject { Arpa::Entities::Profile.new attrs } 24 | 25 | it 'attribute :role_ids should be an empty Array' do 26 | expect(subject.role_ids).to eq [] 27 | end 28 | 29 | it 'attribute :role should be an empty Array' do 30 | expect(subject.roles).to eq [] 31 | end 32 | 33 | it 'attribute :removed should be false' do 34 | expect(subject.removed).to be_falsey 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/lib/arpa/entities/resource_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Entities::Resource, type: :entity, fast: true do 4 | describe 'initializing' do 5 | describe 'setting default values' do 6 | context 'when pass :actions as nil' do 7 | it 'attribute :actions should be an empty Array' do 8 | expect(subject.actions).to eq [] 9 | end 10 | end 11 | end 12 | 13 | context 'when pass :actions as empty' do 14 | let(:attrs) { { actions: '' } } 15 | subject { Arpa::Entities::Resource.new attrs } 16 | 17 | it 'attribute :actions should be an empty Array' do 18 | expect(subject.actions).to eq [] 19 | end 20 | end 21 | end 22 | 23 | describe '#build_correct_name' do 24 | before { subject.build_correct_name } 25 | 26 | context 'when pass :full_name as "UsersController"' do 27 | subject { Arpa::Entities::Resource.new full_name: 'UsersController' } 28 | 29 | it 'full_name should be "UsersController"' do 30 | expect(subject.full_name).to eql 'UsersController' 31 | end 32 | 33 | it 'name should be builded as "users"' do 34 | expect(subject.name).to eql 'users' 35 | end 36 | end 37 | 38 | context 'when pass :full_name as "Authentication::Someone::UsersController"' do 39 | subject { Arpa::Entities::Resource.new full_name: 'Authentication::Someone::UsersController' } 40 | 41 | it 'full_name should be "Authentication::Someone::UsersController"' do 42 | expect(subject.full_name).to eql 'Authentication::Someone::UsersController' 43 | end 44 | 45 | it 'name should be builded as "authentication/someone/users"' do 46 | expect(subject.name).to eql 'authentication/someone/users' 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /spec/lib/arpa/entities/role_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Entities::Role, type: :entity, fast: true do 4 | describe 'initializing' do 5 | describe 'setting default values' do 6 | context 'when pass some parameters as nil' do 7 | it 'attribute :action_ids should be an empty Array' do 8 | expect(subject.action_ids).to eq [] 9 | end 10 | 11 | it 'attribute :actions should be an empty Array' do 12 | expect(subject.actions).to eq [] 13 | end 14 | 15 | it 'attribute :profiles should be an empty Array' do 16 | expect(subject.profiles).to eq [] 17 | end 18 | 19 | it 'attribute :removed should be false' do 20 | expect(subject.removed).to be_falsey 21 | end 22 | end 23 | end 24 | 25 | context 'when pass some parameters as empty' do 26 | let(:attrs) { { action_ids: '', actions: '', profiles: '', removed: '' } } 27 | subject { Arpa::Entities::Role.new attrs } 28 | 29 | it 'attribute :action_ids should be an empty Array' do 30 | expect(subject.action_ids).to eq [] 31 | end 32 | 33 | it 'attribute :actions should be an empty Array' do 34 | expect(subject.actions).to eq [] 35 | end 36 | 37 | it 'attribute :profiles should be an empty Array' do 38 | expect(subject.profiles).to eq [] 39 | end 40 | 41 | it 'attribute :removed should be false' do 42 | expect(subject.removed).to be_falsey 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/actions/finder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Actions::Finder, type: :repository, slow: true do 4 | let(:resource_record) { create :repository_resource, :user } 5 | let(:action_record_001) { create :repository_action, :index, resource: resource_record } 6 | let(:action_record_002) { create :repository_action, :show, resource: resource_record } 7 | 8 | before do 9 | action_record_001 10 | action_record_002 11 | end 12 | 13 | describe '#by_name_and_resource' do 14 | context 'when exist with the params' do 15 | let(:result) { subject.by_name_and_resource('index', resource_record) } 16 | 17 | it 'should return a resource with name "index"' do 18 | expect(result.name).to eql 'index' 19 | end 20 | 21 | it 'the result should be an instance of Arpa::Entities::Action' do 22 | expect(result).to be_an Arpa::Entities::Action 23 | end 24 | end 25 | 26 | context 'when nonexist with the params' do 27 | let(:result) { subject.by_name_and_resource('nonexist_action', resource_record) } 28 | 29 | it 'the result should return nil' do 30 | expect(result).to be_nil 31 | end 32 | end 33 | end 34 | 35 | describe 'getting permission from action_name, resource_name and profile_ids' do 36 | let(:resource_name) { '' } 37 | let(:action_name) { '' } 38 | let(:profile_ids) { [] } 39 | 40 | let(:result) { subject.permission(resource_name, action_name, profile_ids) } 41 | 42 | before { result } 43 | 44 | context 'when action and resource belongs to some profile' do 45 | let(:user_resource) { create :repository_resource, :user } 46 | let(:index_action) { create :repository_action, :index, resource: user_resource } 47 | let(:show_action) { create :repository_action, :show, resource: user_resource } 48 | 49 | let(:user_resource_001) { create :repository_resource, :contact } 50 | let(:index_action_001) { create :repository_action, :index, resource: user_resource } 51 | 52 | let(:role_001) { create :repository_role, actions: [index_action] } 53 | let(:role_002) { create :repository_role, actions: [index_action] } 54 | let(:role_003) { create :repository_role, actions: [index_action_001] } 55 | 56 | let(:profile_001) { create :repository_profile, roles: [role_001, role_002] } 57 | let(:profile_002) { create :repository_profile, roles: [role_001, role_003] } 58 | 59 | let(:resource_name) { 'users' } 60 | let(:action_name) { 'index' } 61 | let(:profile_ids) { [profile_001.id, profile_002.id] } 62 | 63 | it 'should return some permission' do 64 | expect(result).to be_an Arpa::Entities::Action 65 | end 66 | end 67 | 68 | context 'when action and resource not belogns to any profile' do 69 | it 'should not return any permission' do 70 | expect(result).to be_nil 71 | end 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/base_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | class BaseImplementationTest 4 | include Arpa::Repositories::Base 5 | end 6 | 7 | describe Arpa::Repositories::Base, type: :repository, fast: true do 8 | let(:base_implementation) { BaseImplementationTest.new } 9 | 10 | context 'when Implementation class do not override methods from Base' do 11 | context 'when call :mapper_instance' do 12 | it 'should raise NotImplementedError' do 13 | expect { base_implementation.mapper_instance }.to raise_error do |error| 14 | expect(error).to be_a NotImplementedError 15 | expect(error.message).to eql 'This BaseImplementationTest cannot respond :mapper_instance' 16 | end 17 | end 18 | end 19 | 20 | context 'when call :repository_class' do 21 | it 'should raise NotImplementedError' do 22 | expect { base_implementation.repository_class }.to raise_error do |error| 23 | expect(error).to be_a NotImplementedError 24 | expect(error.message).to eql 'This BaseImplementationTest cannot respond :repository_class' 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/profiles/finder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Profiles::Finder, type: :repository, slow: true do 4 | let(:record_001) { create :repository_profile, name: 'profile_01' } 5 | let(:record_002) { create :repository_profile, name: 'profile_02' } 6 | 7 | before do 8 | record_001 9 | record_002 10 | end 11 | 12 | describe '#find' do 13 | let(:result) { subject.find(record_001.id) } 14 | 15 | it 'the Profile entity should has name "profile_01"' do 16 | expect(result.name).to eql 'profile_01' 17 | end 18 | 19 | it 'the result should be an Arpa::Entities::Profile' do 20 | expect(result).to be_an Arpa::Entities::Profile 21 | end 22 | end 23 | 24 | describe '#all' do 25 | let(:result) { subject.all } 26 | 27 | it 'should return all' do 28 | expect(result.size).to be == 2 29 | end 30 | 31 | it 'the first Profile entity should has name "profile_01"' do 32 | expect(result.first.name).to eql 'profile_01' 33 | end 34 | 35 | it 'the result should be an Array of Arpa::Entities::Profile' do 36 | expect(result.first).to be_an Arpa::Entities::Profile 37 | end 38 | end 39 | 40 | describe '#all_by_entity' do 41 | context 'when have profiles with differents entities' do 42 | let(:entity_001) { create :entity } 43 | let(:record_003) { create :repository_profile, name: 'profile_03', entity_id: entity_001.id, entity_class: entity_001.class } 44 | let(:record_004) { create :repository_profile, :with_entity, name: 'profile_04' } 45 | let(:result) { subject.all_by_entity entity_001.id, entity_001.class.to_s } 46 | 47 | before do 48 | record_003 49 | record_004 50 | end 51 | 52 | it 'should return all without entity and with correct entity' do 53 | expect(result.size).to be == 3 54 | end 55 | 56 | it 'the result without entity should fill with nil value' do 57 | first = result.first 58 | expect(first.entity_id).to be_nil 59 | expect(first.entity_class).to be_nil 60 | 61 | second = result.second 62 | expect(second.entity_id).to be_nil 63 | expect(second.entity_class).to be_nil 64 | end 65 | 66 | it 'the result with entity should be filled correct values' do 67 | third = result.third 68 | expect(third.entity_id).to be == entity_001.id 69 | expect(third.entity_class).to eql entity_001.class.to_s 70 | end 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/profiles/remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Profiles::Remover, type: :repository, slow: true do 4 | let(:created_profile) { create :repository_profile } 5 | 6 | before { created_profile } 7 | 8 | describe '#destroy' do 9 | let(:destroy_profile) { subject.destroy(created_profile) } 10 | 11 | it 'should destroy the role' do 12 | expect { destroy_profile }.to change(Arpa::Repositories::Profiles::RepositoryProfile, :count).by(-1) 13 | end 14 | end 15 | 16 | describe '#disable' do 17 | let(:disable_profile) { subject.disable(created_profile) } 18 | 19 | it 'should disable the role' do 20 | expect { disable_profile }.to change(Arpa::Repositories::Profiles::RepositoryProfile, :count).by(-1) 21 | end 22 | 23 | it 'role should be setted to removed: true' do 24 | expect(disable_profile.removed).to be_truthy 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/resources/finder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Resources::Finder, type: :repository, slow: true do 4 | let(:record_001) { create :repository_resource, :user } 5 | let(:record_002) { create :repository_resource, :contact } 6 | 7 | describe '#find' do 8 | let(:result) { subject.find(record_001.id) } 9 | 10 | it 'the Resource entity should has name "users"' do 11 | expect(result.name).to eql 'users' 12 | end 13 | 14 | it 'the result should be an Arpa::Entities::Resource' do 15 | expect(result).to be_an Arpa::Entities::Resource 16 | end 17 | end 18 | 19 | describe '#all' do 20 | let(:result) { subject.all } 21 | 22 | before do 23 | record_001 24 | record_002 25 | end 26 | 27 | it 'should return size 2' do 28 | expect(result.size).to be == 2 29 | end 30 | 31 | it 'the first Resource entity should has full_name "ContactsController"' do 32 | expect(result.first.full_name).to eql 'ContactsController' 33 | end 34 | 35 | it 'the result should be an Array of Arpa::Entities::Resource' do 36 | expect(result.first).to be_an Arpa::Entities::Resource 37 | end 38 | end 39 | 40 | describe '#by_full_name' do 41 | before do 42 | record_001 43 | record_002 44 | end 45 | 46 | context 'when exist with the full_name' do 47 | let(:result) { subject.by_full_name('UsersController') } 48 | 49 | it 'should return a resource with name "users"' do 50 | expect(result.name).to eql 'users' 51 | end 52 | 53 | it 'the result should be an instance of Arpa::Entities::Resource' do 54 | expect(result).to be_an Arpa::Entities::Resource 55 | end 56 | end 57 | 58 | context 'when nonexist with the full_name' do 59 | let(:result) { subject.by_full_name('NonessController') } 60 | 61 | it 'the result should return nil' do 62 | expect(result).to be_nil 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/resources/remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Resources::Remover, type: :repository, slow: true do 4 | let(:resource_001) { create :repository_resource, :user } 5 | let(:destroy_resource) { subject.destroy(resource_001) } 6 | 7 | describe '#destroy' do 8 | context 'when resource has no actions associate' do 9 | let(:actions) { [] } 10 | 11 | it 'should destroy the resource' do 12 | expect { destroy_resource }.to change(Arpa::Repositories::Resources::RepositoryResource, :count).by(0) 13 | end 14 | end 15 | 16 | context 'when resource has actions associate' do 17 | let(:action_001) { create :repository_action, :index, resource: resource_001 } 18 | let(:action_002) { create :repository_action, :show, resource: resource_001 } 19 | 20 | before do 21 | action_001 22 | action_002 23 | end 24 | 25 | it 'should destroy the resource' do 26 | expect { destroy_resource }.to change(Arpa::Repositories::Resources::RepositoryResource, :count).by(-1) 27 | end 28 | 29 | it 'should destroy all actions associate with resource' do 30 | expect { destroy_resource }.to change(Arpa::Repositories::Actions::RepositoryAction, :count).by(-2) 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/roles/finder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Roles::Finder, type: :repository, slow: true do 4 | let(:record_001) { create :repository_role, name: 'role_01' } 5 | let(:record_002) { create :repository_role, name: 'role_02' } 6 | 7 | before do 8 | record_001 9 | record_002 10 | end 11 | 12 | describe '#find' do 13 | let(:result) { subject.find(record_001.id) } 14 | 15 | it 'the Role entity should has name "role_01"' do 16 | expect(result.name).to eql 'role_01' 17 | end 18 | 19 | it 'the result should be an Arpa::Entities::Role' do 20 | expect(result).to be_an Arpa::Entities::Role 21 | end 22 | end 23 | 24 | describe '#all' do 25 | let(:result) { subject.all } 26 | 27 | it 'should return size 2' do 28 | expect(result.size).to be == 2 29 | end 30 | 31 | it 'the first Role entity should has name "role_01"' do 32 | expect(result.first.name).to eql 'role_01' 33 | end 34 | 35 | it 'the result should be an Array of Arpa::Entities::Role' do 36 | expect(result.first).to be_an Arpa::Entities::Role 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /spec/lib/arpa/repositories/roles/remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Repositories::Roles::Remover, type: :repository, slow: true do 4 | let(:created_role) { create :repository_role } 5 | 6 | before { created_role } 7 | 8 | describe '#destroy' do 9 | let(:destroy_role) { subject.destroy(created_role) } 10 | 11 | it 'should destroy the role' do 12 | expect { destroy_role }.to change(Arpa::Repositories::Roles::RepositoryRole, :count).by(-1) 13 | end 14 | end 15 | 16 | describe '#disable' do 17 | let(:disable_role) { subject.disable(created_role) } 18 | 19 | it 'should disable the role' do 20 | expect { disable_role }.to change(Arpa::Repositories::Roles::RepositoryRole, :count).by(-1) 21 | end 22 | 23 | it 'role should be setted to removed: true' do 24 | expect(disable_role.removed).to be_truthy 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/lib/arpa/requests/profiles/create_request_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | RSpec.describe 'Create Profile', type: %i[request profile] do 4 | let(:finder_profile_repo) { Arpa::Repositories::Profiles::Finder.new } 5 | let(:finder_resource_repo) { Arpa::Repositories::Resources::Finder.new } 6 | let(:finder_role_repo) { Arpa::Repositories::Roles::Finder.new } 7 | let(:creator_resource_service) { Arpa::Services::Resources::ResourceManagerCreator.new } 8 | let(:creator_role_service) { Arpa::Services::Roles::RoleManagerCreator.new } 9 | let(:creator_profile_service) { Arpa::Services::Profiles::ProfileManagerCreator.new } 10 | let(:success_proc) { ->(r) {} } 11 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 12 | 13 | context 'when have no created resources or actions' do 14 | let(:resourceable_001) { double to_s: 'UsersController', action_methods: [:index, :show, 'edit'] } 15 | let(:resourceable_002) { double to_s: 'ContactsController', action_methods: [:index, 'edit'] } 16 | let(:resourceables) { [resourceable_001, resourceable_002] } 17 | let(:created_resources) { creator_resource_service.create({ resourceables: resourceables }, callback) } 18 | 19 | let(:action_ids) { finder_resource_repo.all.first.actions.collect(&:id) } 20 | let(:role_001_params) { { role: { name: 'role_name_001', description: 'role_description_001', action_ids: action_ids } } } 21 | let(:role_002_params) { { role: { name: 'role_name_002', description: 'role_description_002', action_ids: action_ids } } } 22 | let(:created_roles) do 23 | creator_role_service.create(role_001_params, callback) 24 | creator_role_service.create(role_002_params, callback) 25 | end 26 | 27 | let(:role_ids) { finder_role_repo.all.map(&:id) } 28 | 29 | before do 30 | created_resources 31 | created_roles 32 | profile_params = { profile: { name: 'profile_name', description: 'profile_description', role_ids: role_ids } } 33 | creator_profile_service.create(profile_params, callback) 34 | end 35 | 36 | it 'should be recorded one profile' do 37 | expect(finder_profile_repo.all.size).to be == 1 38 | end 39 | 40 | it 'should has 2 roles associated' do 41 | expect(finder_profile_repo.all.first.roles.size).to be == 2 42 | end 43 | 44 | context 'names of associated roles' do 45 | it { expect(finder_profile_repo.all.first.roles.first.name).to eql 'role_name_001' } 46 | it { expect(finder_profile_repo.all.first.roles.second.name).to eql 'role_name_002' } 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/lib/arpa/requests/profiles/remove_request_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | RSpec.describe 'Remove Profile', type: %i[request profile] do 4 | let(:finder_profile_repo) { Arpa::Repositories::Profiles::Finder.new } 5 | let(:remover_profile_service) { Arpa::Services::Profiles::ProfileManagerRemover.new } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | describe 'removing a Profile' do 10 | before do 11 | create :repository_profile 12 | remover_profile_service.remove(profile_params_to_remove, callback) 13 | end 14 | 15 | context 'when need destroy a Profile' do 16 | let(:profile_params_to_remove) { { profile: finder_profile_repo.all.first } } 17 | 18 | it 'record should be removed ' do 19 | expect(finder_profile_repo.all.size).to be == 0 20 | end 21 | end 22 | 23 | context 'when need disable a Profile' do 24 | let(:profile_params_to_remove) { { profile: finder_profile_repo.all.first, disable: true } } 25 | 26 | it 'record should be removed ' do 27 | expect(finder_profile_repo.all.size).to be == 0 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/lib/arpa/requests/resources/create_request_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | RSpec.describe 'Create Resource', type: %i[request resource] do 4 | let(:finder_repo) { Arpa::Repositories::Resources::Finder.new } 5 | let(:creator_service) { Arpa::Services::Resources::ResourceManagerCreator.new } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | context 'when have no created resources or actions' do 10 | let(:resourceable_001) { double to_s: 'UsersController', action_methods: [:index, :show, 'edit'] } 11 | let(:resourceable_002) { double to_s: 'ContactsController', action_methods: [:index, 'edit'] } 12 | let(:resourceables) { [resourceable_001, resourceable_002] } 13 | 14 | before do 15 | creator_service.create({ resourceables: resourceables }, callback) 16 | end 17 | 18 | it 'should be recorded two resources' do 19 | expect(finder_repo.all.size).to be == 2 20 | end 21 | 22 | context 'names of resources' do 23 | it { expect(finder_repo.all.first.name).to eql('contacts') } 24 | it { expect(finder_repo.all.second.name).to eql('users') } 25 | end 26 | 27 | context 'Contacts resource' do 28 | let(:contacts_resource) { finder_repo.all.first } 29 | 30 | it 'should has two actions' do 31 | expect(contacts_resource.actions.size).to be == 2 32 | end 33 | 34 | context 'names of actions' do 35 | it { expect(contacts_resource.actions.first.name).to eql('edit') } 36 | it { expect(contacts_resource.actions.second.name).to eql('index') } 37 | end 38 | end 39 | 40 | context 'Users resource' do 41 | let(:users_resource) { finder_repo.all.second } 42 | 43 | it 'should has three actions' do 44 | expect(users_resource.actions.size).to be == 3 45 | end 46 | 47 | context 'names of actions' do 48 | it { expect(users_resource.actions.first.name).to eql('edit') } 49 | it { expect(users_resource.actions.second.name).to eql('index') } 50 | it { expect(users_resource.actions.third.name).to eql('show') } 51 | end 52 | end 53 | end 54 | 55 | context 'when have created resources or actions' do 56 | let(:resourceable_001) { double to_s: 'UsersController', action_methods: [:index, :show, 'edit'] } 57 | let(:resourceable_002) { double to_s: 'ContactsController', action_methods: [:index, 'edit'] } 58 | let(:created_resourceables) { [resourceable_001, resourceable_002] } 59 | 60 | let(:resourceable_003) { double to_s: 'Arpa::NewUsersController', action_methods: [:show, 'edit'] } 61 | let(:resourceable_004) { double to_s: 'ContactsController', action_methods: [:index, 'new_edit'] } 62 | let(:new_resourceables) { [resourceable_003, resourceable_004] } 63 | 64 | before do 65 | creator_service.create({ resourceables: created_resourceables }, callback) 66 | creator_service.create({ resourceables: new_resourceables }, callback) 67 | end 68 | 69 | it 'should be recorded two resources' do 70 | expect(finder_repo.all.size).to be == 2 71 | end 72 | 73 | context 'names of resources' do 74 | it { expect(finder_repo.all.first.name).to eql('arpa/new_users') } 75 | it { expect(finder_repo.all.second.name).to eql('contacts') } 76 | end 77 | 78 | context 'Contacts resource' do 79 | let(:contacts_resource) { finder_repo.all.second } 80 | 81 | it 'should has two actions' do 82 | expect(contacts_resource.actions.size).to be == 2 83 | end 84 | 85 | context 'names of actions' do 86 | it { expect(contacts_resource.actions.first.name).to eql('index') } 87 | it { expect(contacts_resource.actions.second.name).to eql('new_edit') } 88 | end 89 | end 90 | 91 | context 'Arpa::NewUsers resource' do 92 | let(:users_resource) { finder_repo.all.first } 93 | 94 | it 'should has two actions' do 95 | expect(users_resource.actions.size).to be == 2 96 | end 97 | 98 | context 'names of actions' do 99 | it { expect(users_resource.actions.first.name).to eql('edit') } 100 | it { expect(users_resource.actions.second.name).to eql('show') } 101 | end 102 | end 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /spec/lib/arpa/requests/roles/create_request_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | RSpec.describe 'Create Role', type: %i[request role] do 4 | let(:finder_role_repo) { Arpa::Repositories::Roles::Finder.new } 5 | let(:finder_resource_repo) { Arpa::Repositories::Resources::Finder.new } 6 | let(:creator_resource_service) { Arpa::Services::Resources::ResourceManagerCreator.new } 7 | let(:creator_role_service) { Arpa::Services::Roles::RoleManagerCreator.new } 8 | let(:success_proc) { ->(r) {} } 9 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 10 | 11 | context 'when have no created resources or actions' do 12 | let(:resourceable_001) { double to_s: 'UsersController', action_methods: [:index, :show, 'edit'] } 13 | let(:resourceable_002) { double to_s: 'ContactsController', action_methods: [:index, 'edit'] } 14 | let(:resourceables) { [resourceable_001, resourceable_002] } 15 | let(:created_resources) { creator_resource_service.create({ resourceables: resourceables }, callback) } 16 | 17 | let(:action_ids) { finder_resource_repo.all.first.actions.collect(&:id) } 18 | 19 | before do 20 | created_resources 21 | role_params = { role: { name: 'role_name', description: 'role_description', action_ids: action_ids } } 22 | creator_role_service.create(role_params, callback) 23 | end 24 | 25 | it 'should be recorded one role' do 26 | expect(finder_role_repo.all.size).to be == 1 27 | end 28 | 29 | it 'should has 2 actions associated' do 30 | expect(finder_role_repo.all.first.actions.size).to be == 2 31 | end 32 | 33 | context 'names of associated actions' do 34 | it { expect(finder_role_repo.all.first.actions.first.name).to eql 'edit' } 35 | it { expect(finder_role_repo.all.first.actions.second.name).to eql 'index' } 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/lib/arpa/requests/roles/remove_request_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | RSpec.describe 'Remove Role', type: %i[request role] do 4 | let(:finder_role_repo) { Arpa::Repositories::Roles::Finder.new } 5 | let(:remover_role_service) { Arpa::Services::Roles::RoleManagerRemover.new } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | describe 'removing a Role' do 10 | before do 11 | create :repository_role 12 | role_params_to_remove = { role: finder_role_repo.all.first } 13 | remover_role_service.remove(role_params_to_remove, callback) 14 | end 15 | 16 | it 'record should be removed ' do 17 | expect(finder_role_repo.all.size).to be == 0 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/lib/arpa/requests/roles/update_request_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | RSpec.describe 'Update Role', type: %i[request role] do 4 | let(:finder_role_repo) { Arpa::Repositories::Roles::Finder.new } 5 | let(:finder_resource_repo) { Arpa::Repositories::Resources::Finder.new } 6 | let(:creator_resource_service) { Arpa::Services::Resources::ResourceManagerCreator.new } 7 | let(:creator_role_service) { Arpa::Services::Roles::RoleManagerCreator.new } 8 | let(:updater_role_service) { Arpa::Services::Roles::RoleManagerUpdater.new } 9 | let(:success_proc) { ->(r) {} } 10 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 11 | 12 | context 'updating a Role' do 13 | let(:resourceable_001) { double to_s: 'UsersController', action_methods: [:index, :show, 'edit'] } 14 | let(:resourceable_002) { double to_s: 'ContactsController', action_methods: [:index, 'edit'] } 15 | let(:resourceables) { [resourceable_001, resourceable_002] } 16 | let(:created_resources) { creator_resource_service.create({ resourceables: resourceables }, callback) } 17 | let(:action_ids) { finder_resource_repo.all.first.actions.collect(&:id) } 18 | 19 | let(:create_resources_and_role) do 20 | created_resources 21 | role_params = { role: { name: 'role_name', description: 'role_description', action_ids: action_ids } } 22 | creator_role_service.create(role_params, callback) 23 | end 24 | 25 | before do 26 | create_resources_and_role 27 | found_role = finder_role_repo.all.first 28 | role_params_to_update = { role: { id: found_role.id, name: 'updated_role_name', description: 'role_description', action_ids: [action_ids[0]] } } 29 | updater_role_service.update(role_params_to_update, callback) 30 | end 31 | 32 | it 'should be recorded one role' do 33 | expect(finder_role_repo.all.size).to be == 1 34 | end 35 | 36 | it 'should has 1 actions associated' do 37 | expect(finder_role_repo.all.first.actions.size).to be == 1 38 | end 39 | 40 | it 'name should be "updated_role_name"' do 41 | expect(finder_role_repo.all.first.name).to eql 'updated_role_name' 42 | end 43 | 44 | context 'names of associated actions' do 45 | it { expect(finder_role_repo.all.first.actions.first.name).to eql 'edit' } 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/actions/create/action_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Actions::Create::ActionCreator, type: :service, fast: true do 4 | let(:action_entity_class) { Arpa::Entities::Action } 5 | let(:action) { double } 6 | let(:resource) { double id: 1 } 7 | let(:actions_names) { %w[index new] } 8 | let(:params) { { resource: resource, actions_names: actions_names } } 9 | let(:action_found) { nil } 10 | 11 | let(:actions_created) { subject.create_many(params) } 12 | let(:validator_class) { Arpa::Validators::ActionValidator } 13 | let(:validator) { instance_double validator_class } 14 | 15 | let(:finder_repo_class) { Arpa::Repositories::Actions::Finder } 16 | let(:finder_repo) { instance_double finder_repo_class } 17 | 18 | before do 19 | allow(finder_repo_class).to receive(:new).and_return(finder_repo) 20 | allow(finder_repo).to receive(:by_name_and_resource).and_return(action_found) 21 | 22 | allow(validator_class).to receive(:new).with(action).and_return(validator) 23 | allow(action_entity_class).to receive(:new).and_return(action) 24 | end 25 | 26 | describe 'creating a new action' do 27 | context 'when resource is invalid' do 28 | let(:errors) { instance_double('ActiveModel::Errors') } 29 | 30 | before do 31 | allow(validator).to receive(:valid?).and_return false 32 | allow(validator).to receive(:errors).and_return(errors) 33 | allow(errors).to receive(:messages) 34 | end 35 | 36 | it 'should raise a Arpa::Exceptions::RecordInvalid with :errors of ActiveModel::Errors' do 37 | expect { actions_created }.to raise_error { |error| 38 | expect(error).to be_a Arpa::Exceptions::RecordInvalid 39 | expect(error.errors).not_to be_nil 40 | } 41 | end 42 | end 43 | 44 | context 'when actino already exists' do 45 | let(:action_found) { double } 46 | 47 | it 'should return the action found' do 48 | expect(actions_created).to eq [action_found, action_found] 49 | end 50 | end 51 | 52 | context 'when resource is valid' do 53 | let(:creator_repo_class) { Arpa::Repositories::Actions::Creator } 54 | let(:creator_repo) { instance_double creator_repo_class } 55 | 56 | before do 57 | allow(validator).to receive(:valid?).and_return true 58 | allow(creator_repo_class).to receive(:new).and_return(creator_repo) 59 | allow(creator_repo).to receive(:create).with(action) 60 | actions_created 61 | end 62 | 63 | it 'creator repository should call :new' do 64 | expect(creator_repo_class).to have_received(:new).once 65 | end 66 | 67 | it 'creator_repo should call create method with action as parameter' do 68 | expect(creator_repo).to have_received(:create).with(action).twice 69 | end 70 | 71 | context 'when build an instance of action' do 72 | it 'entity action should call new method' do 73 | expect(action_entity_class).to have_received(:new).with(resource_id: resource.id, name: 'index').once 74 | expect(action_entity_class).to have_received(:new).with(resource_id: resource.id, name: 'new').once 75 | end 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/actions/remove/action_remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Actions::Remove::ActionRemover, type: :service, fast: true do 4 | let(:action_001) { double name: 'index' } 5 | let(:action_002) { double name: 'old_index' } 6 | let(:actions) { [action_001, action_002] } 7 | let(:resource) { double actions: actions } 8 | 9 | let(:actions_names) { %w[index show] } 10 | 11 | let(:params) { { resource: resource, actions_names: actions_names } } 12 | 13 | describe 'removing nonexistent actions' do 14 | let(:remover_repo_class) { Arpa::Repositories::Actions::Remover } 15 | let(:remover_repo) { instance_double remover_repo_class } 16 | 17 | before do 18 | allow(remover_repo_class).to receive(:new).and_return(remover_repo) 19 | allow(remover_repo).to receive(:destroy) 20 | 21 | subject.remove_nonexistent_actions(params) 22 | end 23 | 24 | it 'remover repository should call :new once' do 25 | expect(remover_repo_class).to have_received(:new).once 26 | end 27 | 28 | it 'remover repository should call :destroy once' do 29 | expect(remover_repo).to have_received(:destroy).once 30 | expect(remover_repo).to have_received(:destroy).with(action_002).once 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/base_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | class CustomTransactionClass 4 | def self.transaction 5 | yield 6 | end 7 | end 8 | 9 | class ManagerImplementationTest 10 | include Arpa::Services::Base 11 | 12 | def create_raise(callback) 13 | manager_action callback do 14 | raise Exceptions::RecordInvalid, 'some error' 15 | end 16 | end 17 | 18 | def create(callback) 19 | manager_action callback do 20 | 'success' 21 | end 22 | end 23 | end 24 | 25 | describe Arpa::Services::Base, type: :service, fast: true do 26 | let(:manager_implementation) { ManagerImplementationTest.new } 27 | let(:callback) do 28 | { 29 | success: ->(result) {}, 30 | fail: ->(exception) {} 31 | } 32 | end 33 | 34 | describe 'calling .transaction' do 35 | before do 36 | set_custom_transaction_class 37 | allow(transaction_class).to receive(:transaction) 38 | manager_implementation.create callback 39 | end 40 | 41 | context 'when use the default transaction_class from Services::ManagerBase' do 42 | let(:set_custom_transaction_class) { manager_implementation.class.repository_transaction nil } 43 | let(:transaction_class) { ActiveRecord::Base } 44 | 45 | it 'transaction_class should call .transaction' do 46 | expect(transaction_class).to have_received(:transaction) 47 | end 48 | end 49 | 50 | context 'when use a custom transaction_class' do 51 | let(:set_custom_transaction_class) { manager_implementation.class.repository_transaction 'CustomTransactionClass' } 52 | let(:transaction_class) { CustomTransactionClass } 53 | 54 | it 'transaction_class should call .transaction' do 55 | expect(transaction_class).to have_received(:transaction) 56 | end 57 | end 58 | end 59 | 60 | describe 'calling correct callback' do 61 | before do 62 | manager_implementation.class.repository_transaction 'CustomTransactionClass' 63 | end 64 | 65 | context 'when success transaction' do 66 | before do 67 | allow(callback[:success]).to receive(:call) 68 | manager_implementation.create callback 69 | end 70 | 71 | it 'should call the callback[:success]' do 72 | expect(callback[:success]).to have_received(:call).once 73 | end 74 | end 75 | 76 | context 'when fail transaction' do 77 | before do 78 | allow(callback[:fail]).to receive(:call).with kind_of StandardError 79 | manager_implementation.create_raise callback 80 | end 81 | 82 | it 'should call the callback[:fail] with Exceptions::RecordInvalid' do 83 | expect(callback[:fail]).to have_received(:call).with(kind_of(StandardError)) 84 | end 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/profiles/create/profile_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Profiles::Create::ProfileCreator, type: :service, fast: true do 4 | let(:profile_entity_class) { Arpa::Entities::Profile } 5 | let(:profile) { double } 6 | let(:params) { double } 7 | 8 | let(:profile_created) { subject.create(params) } 9 | let(:validator_class) { Arpa::Validators::ProfileValidator } 10 | let(:validator) { instance_double validator_class } 11 | 12 | before do 13 | allow(validator_class).to receive(:new).and_return(validator) 14 | allow(profile_entity_class).to receive(:new).and_return(profile) 15 | end 16 | 17 | describe 'creating a new profile' do 18 | context 'when profile is invalid' do 19 | let(:errors) { instance_double('ActiveModel::Errors') } 20 | 21 | before do 22 | allow(validator).to receive(:valid?).and_return false 23 | allow(validator).to receive(:errors).and_return(errors) 24 | allow(errors).to receive(:messages) 25 | end 26 | 27 | it 'should raise a Arpa::Exceptions::RecordInvalid with :errors of ActiveModel::Errors' do 28 | expect { profile_created }.to raise_error { |error| 29 | expect(error).to be_a Arpa::Exceptions::RecordInvalid 30 | expect(error.errors).not_to be_nil 31 | } 32 | end 33 | end 34 | 35 | context 'when profile is valid' do 36 | let(:creator_repo_class) { Arpa::Repositories::Profiles::Creator } 37 | let(:creator_repo) { instance_double creator_repo_class } 38 | 39 | before do 40 | allow(validator).to receive(:valid?).and_return true 41 | allow(creator_repo_class).to receive(:new).and_return(creator_repo) 42 | allow(creator_repo).to receive(:create).with(profile) 43 | profile_created 44 | end 45 | 46 | it 'creator repository should call :new' do 47 | expect(creator_repo_class).to have_received(:new) 48 | end 49 | 50 | it 'creator_repo should call create method with profile as parameter' do 51 | expect(creator_repo).to have_received(:create).with(profile).once 52 | end 53 | 54 | context 'when build the profile' do 55 | it 'entity profile should call new method' do 56 | expect(profile_entity_class).to have_received(:new).once 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/profiles/profile_manager_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Profiles::ProfileManagerCreator, type: :service, fast: true do 4 | let(:profile_creator) { double } 5 | let(:params) { { profile: { name: 'profile_name', description: 'profile_description', role_ids: [1, 2] } } } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | let(:setup_creators) do 10 | allow(Arpa::Services::Profiles::Create::ProfileCreator).to receive(:new).and_return(profile_creator) 11 | end 12 | 13 | let(:setup_creators_methods) do 14 | allow(profile_creator).to receive(:create) 15 | end 16 | 17 | let(:result) { subject.create params, callback } 18 | 19 | before do 20 | setup_creators 21 | setup_creators_methods 22 | allow(success_proc).to receive(:call) 23 | result 24 | end 25 | 26 | it 'profile_creator should call :create with parameters' do 27 | expect(profile_creator).to have_received(:create).with(params[:profile]).once 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/profiles/profile_manager_remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Profiles::ProfileManagerRemover, type: :service, fast: true do 4 | let(:profile_remover) { double } 5 | let(:profile) { double } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | let(:setup_updaters) do 10 | allow(Arpa::Services::Profiles::Remove::ProfileRemover).to receive(:new).and_return(profile_remover) 11 | end 12 | 13 | let(:setup_updaters_methods) do 14 | allow(profile_remover).to receive(:remove) 15 | end 16 | 17 | let(:result) { subject.remove params, callback } 18 | 19 | before do 20 | setup_updaters 21 | setup_updaters_methods 22 | allow(success_proc).to receive(:call) 23 | result 24 | end 25 | 26 | context 'when is to destroy' do 27 | let(:params) { { profile: profile } } 28 | 29 | it 'profile_remover should call :remove with profile as parameter' do 30 | expect(profile_remover).to have_received(:remove).with(profile, nil).once 31 | end 32 | end 33 | 34 | context 'when is to disable' do 35 | let(:params) { { profile: profile, disable: true } } 36 | 37 | it 'profile_remover should call :remove with profile and disable: true as parameter' do 38 | expect(profile_remover).to have_received(:remove).with(profile, true).once 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/profiles/profile_manager_updater_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Profiles::ProfileManagerUpdater, type: :service, fast: true do 4 | let(:profile_updater) { double } 5 | let(:params) { { profile: { name: 'profile_name', description: 'profile_description', role_ids: [1, 2] } } } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | let(:setup_updaters) do 10 | allow(Arpa::Services::Profiles::Update::ProfileUpdater).to receive(:new).and_return(profile_updater) 11 | end 12 | 13 | let(:setup_updaters_methods) do 14 | allow(profile_updater).to receive(:update) 15 | end 16 | 17 | let(:result) { subject.update params, callback } 18 | 19 | before do 20 | setup_updaters 21 | setup_updaters_methods 22 | allow(success_proc).to receive(:call) 23 | result 24 | end 25 | 26 | it 'profile_updater should call :update with parameters' do 27 | expect(profile_updater).to have_received(:update).with(params[:profile]).once 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/profiles/remove/profile_remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Profiles::Remove::ProfileRemover, type: :service, fast: true do 4 | let(:profile) { double } 5 | 6 | describe 'removing profile' do 7 | let(:remover_repo_class) { Arpa::Repositories::Profiles::Remover } 8 | let(:remover_repo) { instance_double remover_repo_class } 9 | 10 | before do 11 | allow(remover_repo_class).to receive(:new).and_return(remover_repo) 12 | setup 13 | subject.remove(profile, disable) 14 | end 15 | 16 | context 'when pass nil as disable param' do 17 | let(:disable) { nil } 18 | 19 | let(:setup) { allow(remover_repo).to receive(:destroy) } 20 | 21 | it 'remover repository should call :destroy once' do 22 | expect(remover_repo).to have_received(:destroy).once 23 | end 24 | 25 | it 'remover repository should call :new once' do 26 | expect(remover_repo_class).to have_received(:new).once 27 | end 28 | end 29 | 30 | context 'when pass true as disable param' do 31 | let(:disable) { true } 32 | 33 | let(:setup) { allow(remover_repo).to receive(:disable) } 34 | 35 | it 'remover repository should call :disable once' do 36 | expect(remover_repo).to have_received(:disable).once 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/profiles/update/profile_updater_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Profiles::Update::ProfileUpdater, type: :service, fast: true do 4 | let(:role_entity_class) { Arpa::Entities::Profile } 5 | let(:profile) { double } 6 | let(:params) { double } 7 | 8 | let(:profile_updated) { subject.update(params) } 9 | let(:validator_class) { Arpa::Validators::ProfileValidator } 10 | let(:validator) { instance_double validator_class } 11 | 12 | before do 13 | allow(validator_class).to receive(:new).and_return(validator) 14 | allow(role_entity_class).to receive(:new).and_return(profile) 15 | end 16 | 17 | describe 'updating a profile' do 18 | context 'when profile is invalid' do 19 | let(:errors) { instance_double('ActiveModel::Errors') } 20 | 21 | before do 22 | allow(validator).to receive(:valid?).and_return false 23 | allow(validator).to receive(:errors).and_return(errors) 24 | allow(errors).to receive(:messages) 25 | end 26 | 27 | it 'should raise a Arpa::Exceptions::RecordInvalid with :errors of ActiveModel::Errors' do 28 | expect { profile_updated }.to raise_error { |error| 29 | expect(error).to be_a Arpa::Exceptions::RecordInvalid 30 | expect(error.errors).not_to be_nil 31 | } 32 | end 33 | end 34 | 35 | context 'when profile is valid' do 36 | let(:updater_repo_class) { Arpa::Repositories::Profiles::Updater } 37 | let(:updater_repo) { instance_double updater_repo_class } 38 | 39 | before do 40 | allow(validator).to receive(:valid?).and_return true 41 | allow(updater_repo_class).to receive(:new).and_return(updater_repo) 42 | allow(updater_repo).to receive(:update).with(profile) 43 | profile_updated 44 | end 45 | 46 | it 'updater repository should call :new' do 47 | expect(updater_repo_class).to have_received(:new) 48 | end 49 | 50 | it 'updater_repo should call update method with profile as parameter' do 51 | expect(updater_repo).to have_received(:update).with(profile).once 52 | end 53 | 54 | context 'when build the profile' do 55 | it 'entity profile should call new method' do 56 | expect(role_entity_class).to have_received(:new).once 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/resources/create/resource_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Resources::Create::ResourceCreator, type: :service, fast: true do 4 | let(:resource_entity_class) { Arpa::Entities::Resource } 5 | let(:resource) { double full_name: 'UsersController' } 6 | let(:resourceable) { double } 7 | let(:resource_found) { nil } 8 | 9 | let(:resource_created) { subject.create(resourceable) } 10 | let(:validator_class) { Arpa::Validators::ResourceValidator } 11 | let(:validator) { instance_double validator_class } 12 | 13 | let(:finder_repo_class) { Arpa::Repositories::Resources::Finder } 14 | let(:finder_repo) { instance_double finder_repo_class } 15 | 16 | before do 17 | allow(finder_repo_class).to receive(:new).and_return(finder_repo) 18 | allow(finder_repo).to receive(:by_full_name).with(kind_of(String)).and_return(resource_found) 19 | 20 | allow(validator_class).to receive(:new).with(resource).and_return(validator) 21 | allow(resource_entity_class).to receive(:new).and_return(resource) 22 | allow(resource).to receive(:build_correct_name) 23 | end 24 | 25 | describe 'creating a new resource' do 26 | context 'when resource is invalid' do 27 | let(:errors) { instance_double('ActiveModel::Errors') } 28 | 29 | before do 30 | allow(validator).to receive(:valid?).and_return false 31 | allow(validator).to receive(:errors).and_return(errors) 32 | allow(errors).to receive(:messages) 33 | end 34 | 35 | it 'should raise a Arpa::Exceptions::RecordInvalid with :errors of ActiveModel::Errors' do 36 | expect { resource_created }.to raise_error { |error| 37 | expect(error).to be_a Arpa::Exceptions::RecordInvalid 38 | expect(error.errors).not_to be_nil 39 | } 40 | end 41 | end 42 | 43 | context 'when resouce already exists' do 44 | let(:resource_found) { double } 45 | 46 | it 'should return the resource found' do 47 | expect(resource_created).to eq resource_found 48 | end 49 | end 50 | 51 | context 'when resource is valid' do 52 | let(:creator_repo_class) { Arpa::Repositories::Resources::Creator } 53 | let(:creator_repo) { instance_double creator_repo_class } 54 | 55 | before do 56 | allow(validator).to receive(:valid?).and_return true 57 | allow(creator_repo_class).to receive(:new).and_return(creator_repo) 58 | allow(creator_repo).to receive(:create).with(resource) 59 | resource_created 60 | end 61 | 62 | it 'creator repository should call :new' do 63 | expect(creator_repo_class).to have_received(:new) 64 | end 65 | 66 | it 'creator_repo should call create method with resource as parameter' do 67 | expect(creator_repo).to have_received(:create).with(resource).once 68 | end 69 | 70 | context 'when build the resource with resourceable' do 71 | it 'entity resource should call new method' do 72 | expect(resource_entity_class).to have_received(:new).once 73 | end 74 | 75 | it 'resource instance should call build_correct_name method' do 76 | expect(resource).to have_received(:build_correct_name).once 77 | end 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/resources/remove/resource_remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Resources::Remove::ResourceRemover, type: :service, fast: true do 4 | let(:resource_001) { double full_name: 'UsersController' } 5 | let(:resource_002) { double full_name: 'OldContactsController' } 6 | let(:resources) { [resource_001, resource_002] } 7 | 8 | let(:resourceable_001) { double to_s: 'UsersController' } 9 | let(:resourceable_002) { double to_s: 'ContactsController' } 10 | let(:resourceables) { [resourceable_001, resourceable_002] } 11 | 12 | describe 'removing nonexistent resources' do 13 | let(:finder_repo_class) { Arpa::Repositories::Resources::Finder } 14 | let(:finder_repo) { instance_double finder_repo_class } 15 | 16 | let(:remover_repo_class) { Arpa::Repositories::Resources::Remover } 17 | let(:remover_repo) { instance_double remover_repo_class } 18 | 19 | before do 20 | allow(finder_repo_class).to receive(:new).and_return(finder_repo) 21 | allow(finder_repo).to receive(:all).and_return(resources) 22 | 23 | allow(remover_repo_class).to receive(:new).and_return(remover_repo) 24 | allow(remover_repo).to receive(:destroy).with(resource_002) 25 | 26 | subject.remove_nonexistent_resources(resourceables) 27 | end 28 | 29 | it 'finder repository should call :new once' do 30 | expect(finder_repo_class).to have_received(:new).once 31 | end 32 | 33 | it 'remover repository should call :new once' do 34 | expect(remover_repo_class).to have_received(:new).once 35 | end 36 | 37 | it 'finder repository should call :all once' do 38 | expect(finder_repo).to have_received(:all).once 39 | end 40 | 41 | it 'remover repository should call :destroy once' do 42 | expect(remover_repo).to have_received(:destroy).once 43 | expect(remover_repo).to have_received(:destroy).with(resource_002).once 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/resources/resource_manager_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Resources::ResourceManagerCreator, type: :service, fast: true do 4 | let(:action_remover) { double } 5 | let(:resource_remover) { double } 6 | let(:resource_creator) { double } 7 | let(:action_creator) { double } 8 | let(:element) { double } 9 | let(:resourceables) { [resourceable_001, resourceable_002] } 10 | let(:params) { { resourceables: resourceables, except_action_methods: ['some_method'] } } 11 | let(:success_proc) { ->(r) {} } 12 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 13 | 14 | let(:resourceable_001) { double action_methods: [] } 15 | let(:resourceable_002) { double action_methods: [] } 16 | let(:resource_created) { double } 17 | 18 | let(:setup_creators) do 19 | allow(Arpa::Services::Resources::Create::ResourceCreator).to receive(:new).and_return(resource_creator) 20 | allow(Arpa::Services::Actions::Create::ActionCreator).to receive(:new).and_return(action_creator) 21 | end 22 | 23 | let(:setup_removers) do 24 | allow(Arpa::Services::Resources::Remove::ResourceRemover).to receive(:new).and_return(resource_remover) 25 | allow(Arpa::Services::Actions::Remove::ActionRemover).to receive(:new).and_return(action_remover) 26 | end 27 | 28 | let(:setup_creators_methods) do 29 | allow(resource_creator).to receive(:create).and_return(resource_created) 30 | allow(action_creator).to receive(:create_many) 31 | end 32 | 33 | let(:setup_removers_methods) do 34 | allow(resource_remover).to receive(:remove_nonexistent_resources) 35 | allow(action_remover).to receive(:remove_nonexistent_actions) 36 | end 37 | 38 | let(:result) { subject.create params, callback } 39 | 40 | before do 41 | setup_creators 42 | setup_creators_methods 43 | setup_removers 44 | setup_removers_methods 45 | allow(success_proc).to receive(:call) 46 | result 47 | end 48 | 49 | it 'resource_remover should call :remove_nonexistent_resources with :resourceables as parameter' do 50 | expect(resource_remover).to have_received(:remove_nonexistent_resources).with(resourceables).once 51 | end 52 | 53 | it 'action_remover should call :remove_nonexistent_actions with :action_params as parameter' do 54 | expect(action_remover).to have_received(:remove_nonexistent_actions).with(resource: resource_created, actions_names: []).twice 55 | end 56 | 57 | it 'resource_creator should call :create with :resourceable as parameter' do 58 | expect(resource_creator).to have_received(:create).with(resourceable_001).once 59 | expect(resource_creator).to have_received(:create).with(resourceable_002).once 60 | end 61 | 62 | it 'action_creator should call :create_many with :action_params as parameter' do 63 | expect(action_creator).to have_received(:create_many).with(resource: resource_created, actions_names: []).twice 64 | end 65 | 66 | it 'success callback should be called with Array of resources as parameter' do 67 | expect(success_proc).to have_received(:call).with([resource_created, resource_created]) 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/roles/create/role_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Roles::Create::RoleCreator, type: :service, fast: true do 4 | let(:role_entity_class) { Arpa::Entities::Role } 5 | let(:role) { double } 6 | let(:params) { double } 7 | 8 | let(:role_created) { subject.create(params) } 9 | let(:validator_class) { Arpa::Validators::RoleValidator } 10 | let(:validator) { instance_double validator_class } 11 | 12 | before do 13 | allow(validator_class).to receive(:new).and_return(validator) 14 | allow(role_entity_class).to receive(:new).and_return(role) 15 | end 16 | 17 | describe 'creating a new role' do 18 | context 'when role is invalid' do 19 | let(:errors) { instance_double('ActiveModel::Errors') } 20 | 21 | before do 22 | allow(validator).to receive(:valid?).and_return false 23 | allow(validator).to receive(:errors).and_return(errors) 24 | allow(errors).to receive(:messages) 25 | end 26 | 27 | it 'should raise a Arpa::Exceptions::RecordInvalid with :errors of ActiveModel::Errors' do 28 | expect { role_created }.to raise_error { |error| 29 | expect(error).to be_a Arpa::Exceptions::RecordInvalid 30 | expect(error.errors).not_to be_nil 31 | } 32 | end 33 | end 34 | 35 | context 'when role is valid' do 36 | let(:creator_repo_class) { Arpa::Repositories::Roles::Creator } 37 | let(:creator_repo) { instance_double creator_repo_class } 38 | 39 | before do 40 | allow(validator).to receive(:valid?).and_return true 41 | allow(creator_repo_class).to receive(:new).and_return(creator_repo) 42 | allow(creator_repo).to receive(:create).with(role) 43 | role_created 44 | end 45 | 46 | it 'creator repository should call :new' do 47 | expect(creator_repo_class).to have_received(:new) 48 | end 49 | 50 | it 'creator_repo should call create method with role as parameter' do 51 | expect(creator_repo).to have_received(:create).with(role).once 52 | end 53 | 54 | context 'when build the role' do 55 | it 'entity role should call new method' do 56 | expect(role_entity_class).to have_received(:new).once 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/roles/remove/role_remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Roles::Remove::RoleRemover, type: :service, fast: true do 4 | let(:role) { double } 5 | 6 | describe 'removing role' do 7 | let(:remover_repo_class) { Arpa::Repositories::Roles::Remover } 8 | let(:remover_repo) { instance_double remover_repo_class } 9 | let(:setup) {} 10 | 11 | before do 12 | allow(remover_repo_class).to receive(:new).and_return(remover_repo) 13 | setup 14 | subject.remove(role) 15 | end 16 | 17 | context 'when role has no profiles' do 18 | let(:setup) do 19 | allow(role).to receive(:has_profile?).and_return(false) 20 | allow(remover_repo).to receive(:destroy) 21 | end 22 | 23 | it 'remover repository should call :destroy once' do 24 | expect(remover_repo).to have_received(:destroy).once 25 | end 26 | 27 | it 'remover repository should call :new once' do 28 | expect(remover_repo_class).to have_received(:new).once 29 | end 30 | end 31 | 32 | context 'when role has profiles' do 33 | let(:setup) do 34 | allow(role).to receive(:has_profile?).and_return(true) 35 | allow(remover_repo).to receive(:disable) 36 | end 37 | 38 | it 'remover repository should call :disable once' do 39 | expect(remover_repo).to have_received(:disable).once 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/roles/role_manager_creator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Roles::RoleManagerCreator, type: :service, fast: true do 4 | let(:role_creator) { double } 5 | let(:params) { { role: { name: 'role_name', description: 'role_description', action_ids: [1, 2] } } } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | let(:setup_creators) do 10 | allow(Arpa::Services::Roles::Create::RoleCreator).to receive(:new).and_return(role_creator) 11 | end 12 | 13 | let(:setup_creators_methods) do 14 | allow(role_creator).to receive(:create) 15 | end 16 | 17 | let(:result) { subject.create params, callback } 18 | 19 | before do 20 | setup_creators 21 | setup_creators_methods 22 | allow(success_proc).to receive(:call) 23 | result 24 | end 25 | 26 | it 'role_creator should call :create with parameters' do 27 | expect(role_creator).to have_received(:create).with(params[:role]).once 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/roles/role_manager_remover_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Roles::RoleManagerRemover, type: :service, fast: true do 4 | let(:role_remover) { double } 5 | let(:role) { double } 6 | let(:params) { { role: role } } 7 | let(:success_proc) { ->(r) {} } 8 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 9 | 10 | let(:setup_updaters) do 11 | allow(Arpa::Services::Roles::Remove::RoleRemover).to receive(:new).and_return(role_remover) 12 | end 13 | 14 | let(:setup_updaters_methods) do 15 | allow(role_remover).to receive(:remove) 16 | end 17 | 18 | let(:result) { subject.remove params, callback } 19 | 20 | before do 21 | setup_updaters 22 | setup_updaters_methods 23 | allow(success_proc).to receive(:call) 24 | result 25 | end 26 | 27 | it 'role_remover should call :remove with role as parameter' do 28 | expect(role_remover).to have_received(:remove).with(role).once 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/roles/role_manager_updater_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Roles::RoleManagerUpdater, type: :service, fast: true do 4 | let(:role_updater) { double } 5 | let(:params) { { role: { name: 'role_name', description: 'role_description', action_ids: [1, 2] } } } 6 | let(:success_proc) { ->(r) {} } 7 | let(:callback) { { success: success_proc, fail: ->(e) { raise e } } } 8 | 9 | let(:setup_updaters) do 10 | allow(Arpa::Services::Roles::Update::RoleUpdater).to receive(:new).and_return(role_updater) 11 | end 12 | 13 | let(:setup_updaters_methods) do 14 | allow(role_updater).to receive(:update) 15 | end 16 | 17 | let(:result) { subject.update params, callback } 18 | 19 | before do 20 | setup_updaters 21 | setup_updaters_methods 22 | allow(success_proc).to receive(:call) 23 | result 24 | end 25 | 26 | it 'role_updater should call :update with parameters' do 27 | expect(role_updater).to have_received(:update).with(params[:role]).once 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/roles/update/role_updater_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Roles::Update::RoleUpdater, type: :service, fast: true do 4 | let(:role_entity_class) { Arpa::Entities::Role } 5 | let(:role) { double } 6 | let(:params) { double } 7 | 8 | let(:role_updated) { subject.update(params) } 9 | let(:validator_class) { Arpa::Validators::RoleValidator } 10 | let(:validator) { instance_double validator_class } 11 | 12 | before do 13 | allow(validator_class).to receive(:new).and_return(validator) 14 | allow(role_entity_class).to receive(:new).and_return(role) 15 | end 16 | 17 | describe 'updating a role' do 18 | context 'when role is invalid' do 19 | let(:errors) { instance_double('ActiveModel::Errors') } 20 | 21 | before do 22 | allow(validator).to receive(:valid?).and_return false 23 | allow(validator).to receive(:errors).and_return(errors) 24 | allow(errors).to receive(:messages) 25 | end 26 | 27 | it 'should raise a Arpa::Exceptions::RecordInvalid with :errors of ActiveModel::Errors' do 28 | expect { role_updated }.to raise_error { |error| 29 | expect(error).to be_a Arpa::Exceptions::RecordInvalid 30 | expect(error.errors).not_to be_nil 31 | } 32 | end 33 | end 34 | 35 | context 'when role is valid' do 36 | let(:updater_repo_class) { Arpa::Repositories::Roles::Updater } 37 | let(:updater_repo) { instance_double updater_repo_class } 38 | 39 | before do 40 | allow(validator).to receive(:valid?).and_return true 41 | allow(updater_repo_class).to receive(:new).and_return(updater_repo) 42 | allow(updater_repo).to receive(:update).with(role) 43 | role_updated 44 | end 45 | 46 | it 'updater repository should call :new' do 47 | expect(updater_repo_class).to have_received(:new) 48 | end 49 | 50 | it 'updater_repo should call update method with role as parameter' do 51 | expect(updater_repo).to have_received(:update).with(role).once 52 | end 53 | 54 | context 'when build the role' do 55 | it 'entity role should call new method' do 56 | expect(role_entity_class).to have_received(:new).once 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /spec/lib/arpa/services/verifier_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Services::Verifier do 4 | let(:current_user) { double is_arpa_admin?: false, profile_ids: [1, 2, 3] } 5 | 6 | subject(:verifier) { Arpa::Services::Verifier.new(current_user) } 7 | 8 | describe '#has_access?' do 9 | context 'when current_user is a arpa admin' do 10 | let(:current_user) { double is_arpa_admin?: true, profile_ids: [1, 2, 3] } 11 | 12 | it 'should has access' do 13 | expect(subject.has_access?('home', 'some_action')).to be_truthy 14 | end 15 | end 16 | 17 | context 'when pass a free action which begin with "_"' do 18 | it 'should has access' do 19 | expect(subject.has_access?('home', '_some_action')).to be_truthy 20 | end 21 | end 22 | 23 | context 'when pass a non free action' do 24 | let(:action_finder_class) { Arpa::Repositories::Actions::Finder } 25 | let(:action_finder) { instance_double action_finder_class } 26 | let(:action) { double } 27 | 28 | before do 29 | allow(action_finder_class).to receive(:new).and_return(action_finder) 30 | allow(action_finder).to receive(:permission).and_return(action) 31 | 32 | subject.has_access?('users', 'index') 33 | end 34 | 35 | it 'should be called :new from Arpa::Repositories::Actions::Finder' do 36 | expect(action_finder_class).to have_received(:new).once 37 | end 38 | 39 | it 'should be called :permissions from Arpa::Repositories::Actions::Finder' do 40 | expect(action_finder).to have_received(:permission).with('users', 'index', [1, 2, 3]).once 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /spec/lib/arpa/validators/action_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Validators::ActionValidator, type: :validator, fast: true do 4 | let(:action) { double name: '', resource_id: nil } 5 | 6 | subject { Arpa::Validators::ActionValidator.new action } 7 | 8 | before { subject.valid? } 9 | 10 | context 'when require' do 11 | it { expect(subject.errors).to be_added(:name, :blank) } 12 | it { expect(subject.errors).to be_added(:resource_id, :blank) } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/lib/arpa/validators/profile_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Validators::ProfileValidator, type: :validator, fast: true do 4 | let(:profile) { double name: '', description: '', role_ids: [] } 5 | 6 | subject { Arpa::Validators::ProfileValidator.new profile } 7 | 8 | before { subject.valid? } 9 | 10 | context 'when require' do 11 | it { expect(subject.errors).to be_added(:name, :blank) } 12 | it { expect(subject.errors).to be_added(:description, :blank) } 13 | it { expect(subject.errors).to be_added(:role_ids, :blank) } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/lib/arpa/validators/resource_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Validators::ResourceValidator, type: :validator, fast: true do 4 | let(:resource) { double full_name: '', name: '' } 5 | 6 | subject { Arpa::Validators::ResourceValidator.new resource } 7 | 8 | before { subject.valid? } 9 | 10 | context 'when require' do 11 | it { expect(subject.errors).to be_added(:full_name, :blank) } 12 | it { expect(subject.errors).to be_added(:name, :blank) } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/lib/arpa/validators/role_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Arpa::Validators::RoleValidator, type: :validator, fast: true do 4 | let(:role) { double name: '', description: '', action_ids: '' } 5 | 6 | subject { Arpa::Validators::RoleValidator.new role } 7 | 8 | before { subject.valid? } 9 | 10 | context 'when require' do 11 | it { expect(subject.errors).to be_added(:name, :blank) } 12 | it { expect(subject.errors).to be_added(:description, :blank) } 13 | it { expect(subject.errors).to be_added(:action_ids, :blank) } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'active_record' 2 | require 'arpa' 3 | require 'database_cleaner' 4 | require 'factory_bot' 5 | require 'support/repositories/test_repository' 6 | require 'i18n' 7 | 8 | ActiveRecord::Base.establish_connection(adapter: 'sqlite3', 9 | database: "#{File.dirname(__FILE__)}/arpa.sqlite3") 10 | 11 | load File.dirname(__FILE__) + '/support/schema.rb' 12 | 13 | I18n.config.enforce_available_locales = true 14 | I18n.load_path << File.expand_path('../lib/config/locales/arpa.en.yml', __dir__) 15 | I18n.reload! 16 | 17 | RSpec.configure do |config| 18 | config.include FactoryBot::Syntax::Methods 19 | FactoryBot.find_definitions 20 | 21 | config.before(:suite) do 22 | DatabaseCleaner.strategy = :transaction 23 | DatabaseCleaner.clean_with(:truncation) 24 | end 25 | 26 | config.around(:each) do |example| 27 | DatabaseCleaner.cleaning do 28 | example.run 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/support/repositories/test_repository.rb: -------------------------------------------------------------------------------- 1 | class TestRepository < ActiveRecord::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/support/schema.rb: -------------------------------------------------------------------------------- 1 | ActiveRecord::Schema.define do 2 | self.verbose = false 3 | 4 | create_table :test_repositories, force: true do |t| 5 | t.string :name 6 | t.timestamps null: false 7 | end 8 | 9 | create_table :repository_resources, force: true do |t| 10 | t.string :name 11 | t.string :full_name 12 | t.timestamps null: false 13 | end 14 | 15 | create_table :repository_actions, force: true do |t| 16 | t.string :name 17 | t.references :repository_resource, index: true 18 | t.timestamps null: false 19 | end 20 | 21 | add_foreign_key :repository_actions, :repository_resources 22 | 23 | create_table :repository_roles, force: true do |t| 24 | t.string :name 25 | t.string :description 26 | t.boolean :removed, default: false 27 | t.timestamps null: false 28 | end 29 | 30 | create_join_table :repository_actions, :repository_roles, force: true do |t| 31 | t.index :repository_action_id, name: 'action_role_id' 32 | t.index :repository_role_id, name: 'role_action_id' 33 | end 34 | 35 | create_table :repository_profiles, force: true do |t| 36 | t.string :name 37 | t.string :description 38 | t.boolean :removed, default: false 39 | t.timestamps null: false 40 | end 41 | 42 | create_join_table :repository_roles, :repository_profiles, force: true do |t| 43 | t.index :repository_role_id, name: 'role_profile_id' 44 | t.index :repository_profile_id, name: 'profile_role_ids' 45 | end 46 | 47 | create_table :users, force: true do |t| 48 | t.string :name 49 | t.string :email 50 | t.timestamps null: false 51 | end 52 | 53 | create_join_table :repository_profiles, :users, force: true do |t| 54 | t.index :repository_profile_id, name: 'profile_user_id' 55 | t.index :user_id, name: 'user_profile_id' 56 | end 57 | 58 | add_column :repository_profiles, :entity_id, :integer, default: nil 59 | add_column :repository_profiles, :entity_class, :string, default: nil 60 | end 61 | --------------------------------------------------------------------------------