From df997aa2585ed0fb5b5b9c963d0c3e347527c60d Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Sun, 20 Nov 2016 13:07:53 -0600 Subject: [PATCH] policies and auto review builds --- app/controllers/admin/vote_controller.rb | 8 ++-- app/controllers/quiz_controller.rb | 1 + app/models/candidate.rb | 7 +++ app/models/user.rb | 13 +++--- app/policies/reviewer_vote_policy.rb | 15 ++++--- app/views/admin/result/_voting.html.erb | 34 ++++++++++++++ app/views/admin/result/view.html.erb | 33 ++------------ .../20161120175737_init_reviewer_votes.rb | 6 +++ db/schema.rb | 2 +- .../admin/result_controller_test.rb | 7 +++ test/fixtures/reviewer_votes.yml | 4 ++ test/models/candidate_test.rb | 7 +++ test/models/user_test.rb | 4 +- test/policies/reviewer_vote_policy_test.rb | 44 +++++++++++++------ 14 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 app/views/admin/result/_voting.html.erb create mode 100644 db/migrate/20161120175737_init_reviewer_votes.rb diff --git a/app/controllers/admin/vote_controller.rb b/app/controllers/admin/vote_controller.rb index 5ef1ded..3a39bb2 100644 --- a/app/controllers/admin/vote_controller.rb +++ b/app/controllers/admin/vote_controller.rb @@ -2,8 +2,8 @@ module Admin class VoteController < AdminController def up - authorize ReviewerVote @candidate = Candidate.find_by(test_hash: params[:test_hash]) + authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id) current_user.cast_yea_on(@candidate) results = { @@ -16,8 +16,8 @@ module Admin end def down - authorize ReviewerVote @candidate = Candidate.find_by(test_hash: params[:test_hash]) + authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id) current_user.cast_nay_on(@candidate) results = { @@ -30,8 +30,8 @@ module Admin end def approve - authorize ReviewerVote @candidate = Candidate.find_by(test_hash: params[:test_hash]) + authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id) current_user.approve_candidate(@candidate) results = { @@ -43,8 +43,8 @@ module Admin end def decline - authorize ReviewerVote @candidate = Candidate.find_by(test_hash: params[:test_hash]) + authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id) current_user.decline_candidate(@candidate) results = { diff --git a/app/controllers/quiz_controller.rb b/app/controllers/quiz_controller.rb index 4523f10..4f4e35d 100644 --- a/app/controllers/quiz_controller.rb +++ b/app/controllers/quiz_controller.rb @@ -36,6 +36,7 @@ class QuizController < ApplicationController def complete_and_email if current_candidate.update_attributes(completed: true) + current_candidate.build_reviews CandidateMailer.submitted(current_candidate).deliver_later RecruiterMailer.candidate_submitted(current_candidate).deliver_later ReviewerMailer.candidate_submission(current_candidate).deliver_later diff --git a/app/models/candidate.rb b/app/models/candidate.rb index 74c2f47..f75a738 100644 --- a/app/models/candidate.rb +++ b/app/models/candidate.rb @@ -5,6 +5,7 @@ class Candidate < ApplicationRecord has_many :answers belongs_to :recruiter, class_name: "User" has_many :votes, class_name: "ReviewerVote" + has_many :reviewers, through: :quiz serialize :email, CryptSerializer @@ -22,6 +23,12 @@ class Candidate < ApplicationRecord declined: 2 } + def build_reviews + reviewers.each do |reviewer| + votes.find_or_create_by(user_id: reviewer.id) + end + end + def submitted_answers answers.where(submitted: true) end diff --git a/app/models/user.rb b/app/models/user.rb index a94ee9b..b7dfbdd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -20,13 +20,13 @@ class User < ApplicationRecord # Voting def cast_yea_on candidate - vote = votes.find_or_create_by(candidate_id: candidate.to_i) + vote = votes.find_by(candidate_id: candidate.to_i) vote.vote = :yea vote.save end def cast_nay_on candidate - vote = votes.find_or_create_by(candidate_id: candidate.to_i) + vote = votes.find_by(candidate_id: candidate.to_i) vote.vote = :nay vote.save end @@ -34,7 +34,7 @@ class User < ApplicationRecord def approve_candidate candidate candidate = Candidate.find(candidate.to_i) - vote = votes.find_or_create_by(candidate_id: candidate.to_i) + vote = votes.find_by(candidate_id: candidate.to_i) vote.veto = :approved candidate.update_attribute(:review_status, :approved) if vote.save end @@ -42,7 +42,7 @@ class User < ApplicationRecord def decline_candidate candidate candidate = Candidate.find(candidate.to_i) - vote = votes.find_or_create_by(candidate_id: candidate.to_i) + vote = votes.find_by(candidate_id: candidate.to_i) vote.veto = :rejected candidate.update_attribute(:review_status, :declined) if vote.save end @@ -50,7 +50,8 @@ class User < ApplicationRecord def my_vote candidate candidate = Candidate.find(candidate.to_i) - votes.find_by(candidate_id: candidate.id).vote + my_vote = votes.find_by(candidate_id: candidate.id) + my_vote.vote unless my_vote.nil? end # Roles @@ -83,7 +84,7 @@ class User < ApplicationRecord end def acts_as_reviewer? - %w(admin reviewer).include? role + %w(admin manager reviewer).include? role end private diff --git a/app/policies/reviewer_vote_policy.rb b/app/policies/reviewer_vote_policy.rb index 3455425..7e9f1da 100644 --- a/app/policies/reviewer_vote_policy.rb +++ b/app/policies/reviewer_vote_policy.rb @@ -8,21 +8,26 @@ class ReviewerVotePolicy < ApplicationPolicy # Only Managers, and Admins, can veto a quiz result def up? - # return true if user.reviewees.include? record.candidate - true + return true if user.acts_as_admin? + return false unless record.candidate.reviewers.include? user + user.acts_as_reviewer? end def down? - # return true if user.acts_as_manager? - # user.quizzes.include? record - true + return true if user.acts_as_admin? + return false unless record.candidate.reviewers.include? user + user.acts_as_reviewer? end def approve? + return true if user.acts_as_admin? + return false unless record.candidate.reviewers.include? user user.acts_as_manager? end def decline? + return true if user.acts_as_admin? + return false unless record.candidate.reviewers.include? user user.acts_as_manager? end diff --git a/app/views/admin/result/_voting.html.erb b/app/views/admin/result/_voting.html.erb new file mode 100644 index 0000000..bc04725 --- /dev/null +++ b/app/views/admin/result/_voting.html.erb @@ -0,0 +1,34 @@ +<% # TODO: This needs to be extracted into a decorator, or something. It is only a quick hack solution. %> + +<% if current_user.acts_as_reviewer? %> +
+ Votes: + <%= link_to admin_up_vote_path(test_hash: @candidate.test_hash), remote: true do %> + Yea (<%= @candidate.votes.yea.count %>) + <% end %> + <%= link_to admin_down_vote_path(test_hash: @candidate.test_hash), remote: true do %> + Nay (<%= @candidate.votes.nay.count %>) + <% end %> + (Your vote: <%= current_user.my_vote(@candidate) %>) +
+<% end %> + +<% if current_user.acts_as_manager? %> +
+ Manager Vetos: + <%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %> + + <%= @candidate.approved? ? "Requested" : "Request Interview" %> + + <% end %> + <%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %> + + <%= @candidate.declined? ? "Declined" : "Decline Interview" %> + + <% end %> +
+ +<% else %> + + Candidate Interview Status: <%= @candidate.review_status %> +<% end %> diff --git a/app/views/admin/result/view.html.erb b/app/views/admin/result/view.html.erb index 8892276..23dfa7b 100644 --- a/app/views/admin/result/view.html.erb +++ b/app/views/admin/result/view.html.erb @@ -7,36 +7,9 @@ Years of Experience: <%= @candidate.experience %>
Recruiter Email: <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %>
-
-
- Votes: - <%= link_to admin_up_vote_path(test_hash: @candidate.test_hash), remote: true do %> - Yea (<%= @candidate.votes.yea.count %>) - <% end %> - <%= link_to admin_down_vote_path(test_hash: @candidate.test_hash), remote: true do %> - Nay (<%= @candidate.votes.nay.count %>) - <% end %> - (Your vote: <%= current_user.my_vote(@candidate) %>) -
- <% if current_user.acts_as_manager? %> -
- Manager Vetos: - <%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %> - - <%= @candidate.approved? ? "Requested" : "Request Interview" %> - - <% end %> - <%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %> - - <%= @candidate.declined? ? "Declined" : "Decline Interview" %> - - <% end %> -
- <% else %> - Candidate Interview Status: <%= @candidate.review_status %> - <% end %> -
- + +
<%= render partial: 'voting' %>
+ <% @quiz.each do |question| %> <%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %> diff --git a/db/migrate/20161120175737_init_reviewer_votes.rb b/db/migrate/20161120175737_init_reviewer_votes.rb new file mode 100644 index 0000000..706c8af --- /dev/null +++ b/db/migrate/20161120175737_init_reviewer_votes.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +class InitReviewerVotes < ActiveRecord::Migration[5.0] + def up + Candidate.where(completed: true).each(&:build_reviews) + end +end diff --git a/db/schema.rb b/db/schema.rb index caafb90..2126b30 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161118023249) do +ActiveRecord::Schema.define(version: 20161120175737) do create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.integer "candidate_id" diff --git a/test/controllers/admin/result_controller_test.rb b/test/controllers/admin/result_controller_test.rb index b186b41..eb9ac57 100644 --- a/test/controllers/admin/result_controller_test.rb +++ b/test/controllers/admin/result_controller_test.rb @@ -26,5 +26,12 @@ module Admin get admin_result_url(candidates(:henry).test_hash) assert_response :success end + + test "recruiter can view result for henry" do + auth_user users(:recruiter) + + get admin_result_url(candidates(:henry).test_hash) + assert_response :success + end end end diff --git a/test/fixtures/reviewer_votes.yml b/test/fixtures/reviewer_votes.yml index 0b22140..2669604 100644 --- a/test/fixtures/reviewer_votes.yml +++ b/test/fixtures/reviewer_votes.yml @@ -1,3 +1,7 @@ +gustov: + candidate: gustov + user_id: 12341234 + manager_richard: candidate: richard diff --git a/test/models/candidate_test.rb b/test/models/candidate_test.rb index 7cb0f5d..393c7e8 100644 --- a/test/models/candidate_test.rb +++ b/test/models/candidate_test.rb @@ -24,4 +24,11 @@ class CandidateTest < ActiveSupport::TestCase refute_equal email, enc_email end + + test "can build reviewer records" do + candidate = candidates(:dawn) + + candidate.build_reviews + assert_equal 3, candidate.votes.count + end end diff --git a/test/models/user_test.rb b/test/models/user_test.rb index bc372e4..d7d9327 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -20,14 +20,14 @@ class UserTest < ActiveSupport::TestCase refute user.reviewer? end - test 'manager should act as manager' do + test 'manager should act as manager and reviewer' do user = users(:manager) assert user.acts_as_manager? + assert user.acts_as_reviewer? refute user.acts_as_admin? refute user.acts_as_recruiter? - refute user.acts_as_reviewer? end test 'manager should only be manager' do diff --git a/test/policies/reviewer_vote_policy_test.rb b/test/policies/reviewer_vote_policy_test.rb index 5447738..1824293 100644 --- a/test/policies/reviewer_vote_policy_test.rb +++ b/test/policies/reviewer_vote_policy_test.rb @@ -29,20 +29,38 @@ class ReviewerVotePolicyTest < PolicyAssertions::Test end def test_up - # refute_permit users(:admin), reviewer_votes(:manager_henry) - # refute_permit users(:recruiter), candidates(:richard) - # refute_permit users(:reviewer), candidates(:gustov) + assert_permit users(:manager), reviewer_votes(:manager_richard) + assert_permit users(:reviewer), reviewer_votes(:reviewer_richard) + assert_permit users(:admin), reviewer_votes(:manager_henry) - # assert_permit users(:admin), candidates(:gustov) - # assert_permit users(:manager), candidates(:richard) - # assert_permit users(:reviewer), candidates(:richard) + refute_permit users(:recruiter), reviewer_votes(:manager_henry) + refute_permit users(:reviewer), reviewer_votes(:gustov) + refute_permit users(:manager), reviewer_votes(:gustov) end - # def test_create_and_update - # assert_permit users(:admin), Vote - # assert_permit users(:manager), Vote - # - # refute_permit users(:recruiter), Vote - # refute_permit users(:reviewer), Vote - # end + def test_down + assert_permit users(:manager), reviewer_votes(:manager_richard) + assert_permit users(:reviewer), reviewer_votes(:reviewer_richard) + assert_permit users(:admin), reviewer_votes(:manager_henry) + + refute_permit users(:recruiter), reviewer_votes(:manager_henry) + refute_permit users(:reviewer), reviewer_votes(:gustov) + refute_permit users(:manager), reviewer_votes(:gustov) + end + + def approve + assert_permit users(:manager), reviewer_votes(:manager_richard) + assert_permit users(:admin), reviewer_votes(:manager_henry) + + refute_permit users(:recruiter), reviewer_votes(:manager_henry) + refute_permit users(:reviewer), reviewer_votes(:reviewer_richard) + end + + def decline + assert_permit users(:manager), reviewer_votes(:manager_richard) + assert_permit users(:admin), reviewer_votes(:manager_henry) + + refute_permit users(:recruiter), reviewer_votes(:manager_henry) + refute_permit users(:reviewer), reviewer_votes(:reviewer_richard) + end end