policies and auto review builds

This commit is contained in:
Mark Moser 2016-11-20 13:07:53 -06:00
parent e8e745f356
commit df997aa258
14 changed files with 124 additions and 61 deletions

View File

@ -2,8 +2,8 @@
module Admin module Admin
class VoteController < AdminController class VoteController < AdminController
def up def up
authorize ReviewerVote
@candidate = Candidate.find_by(test_hash: params[:test_hash]) @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) current_user.cast_yea_on(@candidate)
results = { results = {
@ -16,8 +16,8 @@ module Admin
end end
def down def down
authorize ReviewerVote
@candidate = Candidate.find_by(test_hash: params[:test_hash]) @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) current_user.cast_nay_on(@candidate)
results = { results = {
@ -30,8 +30,8 @@ module Admin
end end
def approve def approve
authorize ReviewerVote
@candidate = Candidate.find_by(test_hash: params[:test_hash]) @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) current_user.approve_candidate(@candidate)
results = { results = {
@ -43,8 +43,8 @@ module Admin
end end
def decline def decline
authorize ReviewerVote
@candidate = Candidate.find_by(test_hash: params[:test_hash]) @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) current_user.decline_candidate(@candidate)
results = { results = {

View File

@ -36,6 +36,7 @@ class QuizController < ApplicationController
def complete_and_email def complete_and_email
if current_candidate.update_attributes(completed: true) if current_candidate.update_attributes(completed: true)
current_candidate.build_reviews
CandidateMailer.submitted(current_candidate).deliver_later CandidateMailer.submitted(current_candidate).deliver_later
RecruiterMailer.candidate_submitted(current_candidate).deliver_later RecruiterMailer.candidate_submitted(current_candidate).deliver_later
ReviewerMailer.candidate_submission(current_candidate).deliver_later ReviewerMailer.candidate_submission(current_candidate).deliver_later

View File

@ -5,6 +5,7 @@ class Candidate < ApplicationRecord
has_many :answers has_many :answers
belongs_to :recruiter, class_name: "User" belongs_to :recruiter, class_name: "User"
has_many :votes, class_name: "ReviewerVote" has_many :votes, class_name: "ReviewerVote"
has_many :reviewers, through: :quiz
serialize :email, CryptSerializer serialize :email, CryptSerializer
@ -22,6 +23,12 @@ class Candidate < ApplicationRecord
declined: 2 declined: 2
} }
def build_reviews
reviewers.each do |reviewer|
votes.find_or_create_by(user_id: reviewer.id)
end
end
def submitted_answers def submitted_answers
answers.where(submitted: true) answers.where(submitted: true)
end end

View File

@ -20,13 +20,13 @@ class User < ApplicationRecord
# Voting # Voting
def cast_yea_on candidate 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.vote = :yea
vote.save vote.save
end end
def cast_nay_on candidate 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.vote = :nay
vote.save vote.save
end end
@ -34,7 +34,7 @@ class User < ApplicationRecord
def approve_candidate candidate def approve_candidate candidate
candidate = Candidate.find(candidate.to_i) 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 vote.veto = :approved
candidate.update_attribute(:review_status, :approved) if vote.save candidate.update_attribute(:review_status, :approved) if vote.save
end end
@ -42,7 +42,7 @@ class User < ApplicationRecord
def decline_candidate candidate def decline_candidate candidate
candidate = Candidate.find(candidate.to_i) 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 vote.veto = :rejected
candidate.update_attribute(:review_status, :declined) if vote.save candidate.update_attribute(:review_status, :declined) if vote.save
end end
@ -50,7 +50,8 @@ class User < ApplicationRecord
def my_vote candidate def my_vote candidate
candidate = Candidate.find(candidate.to_i) 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 end
# Roles # Roles
@ -83,7 +84,7 @@ class User < ApplicationRecord
end end
def acts_as_reviewer? def acts_as_reviewer?
%w(admin reviewer).include? role %w(admin manager reviewer).include? role
end end
private private

View File

@ -8,21 +8,26 @@ class ReviewerVotePolicy < ApplicationPolicy
# Only Managers, and Admins, can veto a quiz result # Only Managers, and Admins, can veto a quiz result
def up? def up?
# return true if user.reviewees.include? record.candidate return true if user.acts_as_admin?
true return false unless record.candidate.reviewers.include? user
user.acts_as_reviewer?
end end
def down? def down?
# return true if user.acts_as_manager? return true if user.acts_as_admin?
# user.quizzes.include? record return false unless record.candidate.reviewers.include? user
true user.acts_as_reviewer?
end end
def approve? def approve?
return true if user.acts_as_admin?
return false unless record.candidate.reviewers.include? user
user.acts_as_manager? user.acts_as_manager?
end end
def decline? def decline?
return true if user.acts_as_admin?
return false unless record.candidate.reviewers.include? user
user.acts_as_manager? user.acts_as_manager?
end end

View File

@ -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? %>
<div class="review_meta__votes" data-id="vote-count">
<strong>Votes: </strong>
<%= link_to admin_up_vote_path(test_hash: @candidate.test_hash), remote: true do %>
Yea (<span data-id="up-votes"><%= @candidate.votes.yea.count %></span>)
<% end %>
<%= link_to admin_down_vote_path(test_hash: @candidate.test_hash), remote: true do %>
Nay (<span data-id="down-votes"><%= @candidate.votes.nay.count %></span>)
<% end %>
<small>(Your vote: <span data-id="my-vote"><%= current_user.my_vote(@candidate) %></span>)</small>
</div>
<% end %>
<% if current_user.acts_as_manager? %>
<div class="review_meta__vetos" data-id="veto-status">
<strong>Manager Vetos: </strong>
<%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %>
<span data-id="interview-request">
<%= @candidate.approved? ? "Requested" : "Request Interview" %>
</span>
<% end %>
<%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %>
<span data-id="interview-decline">
<%= @candidate.declined? ? "Declined" : "Decline Interview" %>
</span>
<% end %>
</div>
<% else %>
<strong>Candidate Interview Status: </strong><%= @candidate.review_status %>
<% end %>

View File

@ -7,36 +7,9 @@
<strong>Years of Experience:</strong> <%= @candidate.experience %><br /> <strong>Years of Experience:</strong> <%= @candidate.experience %><br />
<strong>Recruiter Email:</strong> <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %><br /> <strong>Recruiter Email:</strong> <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %><br />
</div> </div>
<div>
<div class="review_meta__votes" data-id="vote-count"> <div><%= render partial: 'voting' %></div>
<strong>Votes: </strong> </div>
<%= link_to admin_up_vote_path(test_hash: @candidate.test_hash), remote: true do %>
Yea (<span data-id="up-votes"><%= @candidate.votes.yea.count %></span>)
<% end %>
<%= link_to admin_down_vote_path(test_hash: @candidate.test_hash), remote: true do %>
Nay (<span data-id="down-votes"><%= @candidate.votes.nay.count %></span>)
<% end %>
<small>(Your vote: <span data-id="my-vote"><%= current_user.my_vote(@candidate) %></span>)</small>
</div>
<% if current_user.acts_as_manager? %>
<div class="review_meta__vetos" data-id="veto-status">
<strong>Manager Vetos: </strong>
<%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %>
<span data-id="interview-request">
<%= @candidate.approved? ? "Requested" : "Request Interview" %>
</span>
<% end %>
<%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %>
<span data-id="interview-decline">
<%= @candidate.declined? ? "Declined" : "Decline Interview" %>
</span>
<% end %>
</div>
<% else %>
<strong>Candidate Interview Status: </strong><%= @candidate.review_status %>
<% end %>
</div>
</div>
<% @quiz.each do |question| %> <% @quiz.each do |question| %>
<%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %> <%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %>

View File

@ -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

View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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| create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.integer "candidate_id" t.integer "candidate_id"

View File

@ -26,5 +26,12 @@ module Admin
get admin_result_url(candidates(:henry).test_hash) get admin_result_url(candidates(:henry).test_hash)
assert_response :success assert_response :success
end 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
end end

View File

@ -1,3 +1,7 @@
gustov:
candidate: gustov
user_id: 12341234
manager_richard: manager_richard:
candidate: richard candidate: richard

View File

@ -24,4 +24,11 @@ class CandidateTest < ActiveSupport::TestCase
refute_equal email, enc_email refute_equal email, enc_email
end end
test "can build reviewer records" do
candidate = candidates(:dawn)
candidate.build_reviews
assert_equal 3, candidate.votes.count
end
end end

View File

@ -20,14 +20,14 @@ class UserTest < ActiveSupport::TestCase
refute user.reviewer? refute user.reviewer?
end end
test 'manager should act as manager' do test 'manager should act as manager and reviewer' do
user = users(:manager) user = users(:manager)
assert user.acts_as_manager? assert user.acts_as_manager?
assert user.acts_as_reviewer?
refute user.acts_as_admin? refute user.acts_as_admin?
refute user.acts_as_recruiter? refute user.acts_as_recruiter?
refute user.acts_as_reviewer?
end end
test 'manager should only be manager' do test 'manager should only be manager' do

View File

@ -29,20 +29,38 @@ class ReviewerVotePolicyTest < PolicyAssertions::Test
end end
def test_up def test_up
# refute_permit users(:admin), reviewer_votes(:manager_henry) assert_permit users(:manager), reviewer_votes(:manager_richard)
# refute_permit users(:recruiter), candidates(:richard) assert_permit users(:reviewer), reviewer_votes(:reviewer_richard)
# refute_permit users(:reviewer), candidates(:gustov) assert_permit users(:admin), reviewer_votes(:manager_henry)
# assert_permit users(:admin), candidates(:gustov) refute_permit users(:recruiter), reviewer_votes(:manager_henry)
# assert_permit users(:manager), candidates(:richard) refute_permit users(:reviewer), reviewer_votes(:gustov)
# assert_permit users(:reviewer), candidates(:richard) refute_permit users(:manager), reviewer_votes(:gustov)
end end
# def test_create_and_update def test_down
# assert_permit users(:admin), Vote assert_permit users(:manager), reviewer_votes(:manager_richard)
# assert_permit users(:manager), Vote assert_permit users(:reviewer), reviewer_votes(:reviewer_richard)
# assert_permit users(:admin), reviewer_votes(:manager_henry)
# refute_permit users(:recruiter), Vote
# refute_permit users(:reviewer), Vote refute_permit users(:recruiter), reviewer_votes(:manager_henry)
# end 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 end