diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 419d9ac..c28f132 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -3,7 +3,8 @@ # They have an speicific layout to reflec this class AdminController < ApplicationController layout 'admin' - before_action :admin_user? + skip_before_action :authenticate_user! + before_action :authenticate_admin! def dashboard @users = User.all @@ -19,19 +20,8 @@ def rooms @rooms = Room.all end - def status_lock_in_changes - - end - - def switch_lock_in_changes - - end - - private - - def admin_user? - unless current_user.admin? - redirect_to home_path - end + def switch_lock_admin + ApplicationHelper.switch_lock + render nothing: true end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6e3abfd..1e71b01 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,7 +4,6 @@ class ApplicationController < ActionController::Base # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception before_action :configure_permitted_parameters, if: :devise_controller? - before_action :authenticate_user! # Protection is in routes diff --git a/app/controllers/assignments_controller.rb b/app/controllers/assignments_controller.rb index 54cdfd5..601aa2b 100644 --- a/app/controllers/assignments_controller.rb +++ b/app/controllers/assignments_controller.rb @@ -5,12 +5,16 @@ def new end def create - Offspring.transaction do + if admin_allows_changes? + Offspring.transaction do of = Offspring.lock.find_by_id(params["format"]) of.shift = Shift.find_by_id(params["shift"]) of.save - redirect_to root_url end + else + flash[:alert] = "No se puedo añadir al niño en este momento, espere." + end + redirect_to root_url end def destroy @@ -19,4 +23,10 @@ def destroy of.save redirect_to new_assignment_path(of) end + + private + + def admin_allows_changes? + !ApplicationHelper.status_lock? + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e58095c..e25df4e 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -2,6 +2,7 @@ # Offsprings are dependent on them # They are the ones that need to perform the process on behalf of the offspring class UsersController < ApplicationController + before_action :authenticate_user! def show @user = User.find_by_id(params[:id]) || current_user end @@ -25,12 +26,12 @@ def destroy private def delete_possible?(user) - if user.nil? + if admin_signed_in? + return true + elsif user.nil? return false elsif user == current_user return false - elsif !current_user.admin? - return false else return true end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 15f5ec5..48c1fcc 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -31,4 +31,12 @@ def week_day_convert(day) week = {1 => 'Lunes', 2 => 'Martes', 3 => 'Miércoles', 4 => 'Jueves', 5 => 'Viernes', 6 => 'Sábado', 7 => 'Domingo'} week[day] || 'Ninguno' end + + def self.status_lock? + return Rails.application.config.lock.status + end + + def self.switch_lock + Rails.application.config.lock.status = ! Rails.application.config.lock.status + end end diff --git a/config/initializers/lock.rb b/config/initializers/lock.rb new file mode 100644 index 0000000..f61e3da --- /dev/null +++ b/config/initializers/lock.rb @@ -0,0 +1,7 @@ + +# lock_config = Rails.application.config_for(:lock) + +Rails.application.configure do + config.lock = ActiveSupport::OrderedOptions.new + config.lock.status = false +end diff --git a/config/locales/es.yml b/config/locales/es.yml index 00cdf83..732f8ea 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -123,3 +123,6 @@ es: first_name: "Nombre" last_name: "Apellidos" grade: "Curso" + controllers: + assignment: + admin_locked_create: "No se puedo añadir al niño en este momento, espere." diff --git a/config/routes.rb b/config/routes.rb index a4e85e3..7042f0d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,10 +2,11 @@ devise_for :admins # when admin is authenticated authenticate :admins do - root to: "static_pages#home" get 'home' => 'static_pages#home' get 'admin' => 'admin#dashboard' get 'offsprings' => 'admin#offsprings' + get 'rooms' => 'admin#rooms' + post 'switch_lock_admin' => 'admin#switch_lock_admin' end # Instructions for the apo get 'static_pages/intructions' diff --git a/db/migrate/20160817083327_add_first_name_to_admins.rb b/db/migrate/20160817083327_add_first_name_to_admins.rb new file mode 100644 index 0000000..03d38ec --- /dev/null +++ b/db/migrate/20160817083327_add_first_name_to_admins.rb @@ -0,0 +1,6 @@ +class AddFirstNameToAdmins < ActiveRecord::Migration + def change + add_column :admins, :first_name, :string + add_column :admins, :last_name, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index ed9e379..5622b70 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160728082715) do +ActiveRecord::Schema.define(version: 20160817083327) do create_table "admins", force: true do |t| t.string "email", default: "", null: false @@ -28,7 +28,6 @@ t.datetime "updated_at", null: false t.string "first_name" t.string "last_name" - t.string "phone" end add_index "admins", ["email"], name: "index_admins_on_email", unique: true @@ -67,22 +66,21 @@ add_index "shifts", ["room_id"], name: "index_shifts_on_room_id" create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0, null: false + t.integer "sign_in_count", default: 0, null: false t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "first_name" t.string "last_name" t.string "phone" - t.boolean "admin", default: false t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" diff --git a/db/seeds.rb b/db/seeds.rb index d54e5c8..d0809ff 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -15,12 +15,10 @@ 1.times do a = FactoryGirl.build(:admin) - a.name = "Alberto" + a.first_name = "Alberto" + a.last_name = "Ramos" a.email = "alberto@example.com" a.save - 2.times do - a.offsprings << FactoryGirl.build(:offspring, user: a, last_name: "Unamuno") - end end 99.times do diff --git a/spec/controllers/admin_controller_spec.rb b/spec/controllers/admin_controller_spec.rb index 4df9b42..6f9394b 100644 --- a/spec/controllers/admin_controller_spec.rb +++ b/spec/controllers/admin_controller_spec.rb @@ -1,7 +1,8 @@ require 'rails_helper' RSpec.describe AdminController, type: :controller do - let(:user_admin) { FactoryGirl.create(:user, :administrator) } + + let(:user_admin) { FactoryGirl.create(:admin) } context "admin user" do describe "GET #dashboard" do it "returns http success" do @@ -10,32 +11,81 @@ expect(response).to have_http_status(:success) end end - describe "can block any change in the data" do - before(:all)do - expect(user_admin).to be_an_instance_of(Admin) + describe "#POST switch_lock_admin" do + before(:each)do # we want to make sure we are starting in switch lock with false value + sign_in user_admin + post :switch_lock_admin if ApplicationHelper.status_lock? end - before(:each)do - get :status_lock_in_changes - if @status == true - post :switch_lock_in_changes - end + it "locks and unlocks changes succesfully" do + post :switch_lock_admin + expect(ApplicationHelper.status_lock?).to be true + post :switch_lock_admin + expect(ApplicationHelper.status_lock?).to be false end - it "succesfully" do #starts in false switch lock - post :switch_lock_in_changes + describe ",when enabled," do + before(:each)do + post :switch_lock_admin unless ApplicationHelper.status_lock? + end + before(:all)do + user = FactoryGirl.build(:user) + user.save + end + + it "users cannot add offspring" do + ref = @controller # Storing pointer to current controller + @controller = OffspringsController.new # Setting User controller to call + sign_in user # Start user session + expect do + post :create, offspring: {first_name: "pepe", last_name: "kata", grade: :primary_first} + end.to change(user.offsprings, :count).by(0) + expect(response).to redirect_to(static_pages_intructions_path) + @controller = ref # Restoring previous admin controller + end + + it "users cannot delete offspring"do + off = FactoryGirl.build(:offspring, user: user) + off.save + ref = @controller # Storing pointer to current controller + @controller = OffspringsController.new # Setting User controller to call + sign_in user # Start user session + expect do + delete :destroy, id: off.id + end.to change(user.offsprings, :count).by(0) + @controller = ref # Restoring previous admin controller + end + + it "users cannot assign offspring"do + off = FactoryGirl.build(:offspring, user: user) + off.save + shi = FactoryGirl.build(:shift) + shi.save + ref = @controller # Storing pointer to current controller + @controller = AssignmentsController.new # Setting User controller to call + sign_in user # Start user session + expect do + post :create, format: off.id, shift: shi.id + end.to change(shi.offsprings, :count).by(0) + @controller = ref # Restoring previous admin controller + end + + it "it still allows users to delete their own account" do + expect(ApplicationHelper.status_lock?).to be true + ref = @controller # Storing pointer to current controller + @controller = UsersController.new # Setting User controller to call + sign_in user # Start user session + expect do + delete :destroy, id: user.id + end.to change{User.count}.by(-1) + @controller = ref # Restoring previous admin controller + end end - pending "and unblock changes" - pending ", users cas still delete their own account" end end let(:user) { FactoryGirl.create(:user) } context "non-admin user" do describe "GET #dashboard" do - it "returns http error" do - sign_in user - get :dashboard - expect(response).to redirect_to(home_path) - end + pending "returns http error" end end end diff --git a/spec/factories/admins.rb b/spec/factories/admins.rb index 056bba6..817000f 100644 --- a/spec/factories/admins.rb +++ b/spec/factories/admins.rb @@ -1,5 +1,10 @@ FactoryGirl.define do factory :admin do - + first_name { Faker::Name.first_name } + last_name { Faker::Name.last_name } + email { Faker::Internet.safe_email } + + password "foobar123" + password_confirmation "foobar123" end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 22e5d5d..9f03b83 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -12,10 +12,5 @@ confirmed_at Time.current - # FactoryGirl.create(user, :administrator) - - trait :administrator do - admin true - end end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 0094f37..d4bbd15 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -1,5 +1,4 @@ require 'rails_helper' - # Specs in this file have access to a helper object that includes # the ApplicationHelper. For example: # @@ -20,4 +19,15 @@ it "returns complex title when page_title with spaces is given" do expect(helper.full_title("Datos de Contacto")).to eq("Datos de Contacto | Catequesis") end + it "returns correctly the status in lock" do + expect(ApplicationHelper.status_lock?).to be(false) + end + it "switches status in lock correctly in both directions" do + old_status = ApplicationHelper.status_lock? # Status A + ApplicationHelper.switch_lock # Change to status B + expect(old_status).not_to be(ApplicationHelper.status_lock?) # Status A and B are different + old_status = ApplicationHelper.status_lock? # Status B + ApplicationHelper.switch_lock # Change to status A + expect(old_status).not_to be(ApplicationHelper.status_lock?) # Status B and A are different + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7a26c1e..3f49209 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,4 @@ +require 'application_helper' # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause @@ -39,59 +40,57 @@ # `true` in RSpec 4. mocks.verify_partial_doubles = true end - - #config.color = true + + # config.color = true # Use color not only in STDOUT but also in pagers and files - #config.tty = true + # config.tty = true # Use the specified formatter - #config.formatter = :documentation # :progress, :html, :textmate -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Allows RSpec to persist some state between runs in order to support - # the `--only-failures` and `--next-failure` CLI options. We recommend - # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ - # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode - config.disable_monkey_patching! - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end + # config.formatter = :documentation # :progress, :html, :textmate + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # # These two settings work together to allow you to limit a spec run + # # to individual examples or groups you care about by tagging them with + # # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # # get run. + # config.filter_run :focus + # config.run_all_when_everything_filtered = true + # + # # Allows RSpec to persist some state between runs in order to support + # # the `--only-failures` and `--next-failure` CLI options. We recommend + # # you configure your source control system to ignore this file. + # config.example_status_persistence_file_path = "spec/examples.txt" + # + # # Limits the available syntax to the non-monkey patched syntax that is + # # recommended. For more details, see: + # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + # config.disable_monkey_patching! + # + # # Many RSpec users commonly either run the entire suite or an individual + # # file, and it's useful to allow more verbose output when running an + # # individual spec file. + # if config.files_to_run.one? + # # Use the documentation formatter for detailed output, + # # unless a formatter has already been configured + # # (e.g. via a command-line flag). + # config.default_formatter = 'doc' + # end + # + # # Print the 10 slowest examples and example groups at the + # # end of the spec run, to help surface which specs are running + # # particularly slow. + # config.profile_examples = 10 + # + # # Run specs in random order to surface order dependencies. If you find an + # # order dependency and want to debug it, you can fix the order by providing + # # the seed, which is printed after each run. + # # --seed 1234 + # config.order = :random + # + # # Seed global randomization in this process using the `--seed` CLI option. + # # Setting this allows you to use `--seed` to deterministically reproduce + # # test failures related to randomization by passing the same `--seed` value + # # as the one that triggered the failure. + # Kernel.srand config.seed end